mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-07-17 11:00:59 -05:00
Replace method-dispatch #defines with inline functions.
This replaces all the macros like ssh_key_sign() and win_draw_text() which take an object containing a vtable pointer and do the dereferencing to find the actual concrete method to call. Now they're all inline functions, which means more sensible type-checking and more comprehensible error reports when the types go wrong, and also means that there's no risk of double-evaluating the object argument.
This commit is contained in:
252
putty.h
252
putty.h
@ -530,23 +530,39 @@ struct BackendVtable {
|
||||
int default_port;
|
||||
};
|
||||
|
||||
#define backend_init(vt, seat, out, logctx, conf, host, port, rhost, nd, ka) \
|
||||
((vt)->init(seat, out, logctx, conf, host, port, rhost, nd, ka))
|
||||
#define backend_free(be) ((be)->vt->free(be))
|
||||
#define backend_reconfig(be, conf) ((be)->vt->reconfig(be, conf))
|
||||
#define backend_send(be, buf, len) ((be)->vt->send(be, buf, len))
|
||||
#define backend_sendbuffer(be) ((be)->vt->sendbuffer(be))
|
||||
#define backend_size(be, w, h) ((be)->vt->size(be, w, h))
|
||||
#define backend_special(be, code, arg) ((be)->vt->special(be, code, arg))
|
||||
#define backend_get_specials(be) ((be)->vt->get_specials(be))
|
||||
#define backend_connected(be) ((be)->vt->connected(be))
|
||||
#define backend_exitcode(be) ((be)->vt->exitcode(be))
|
||||
#define backend_sendok(be) ((be)->vt->sendok(be))
|
||||
#define backend_ldisc_option_state(be, opt) \
|
||||
((be)->vt->ldisc_option_state(be, opt))
|
||||
#define backend_provide_ldisc(be, ldisc) ((be)->vt->provide_ldisc(be, ldisc))
|
||||
#define backend_unthrottle(be, bufsize) ((be)->vt->unthrottle(be, bufsize))
|
||||
#define backend_cfg_info(be) ((be)->vt->cfg_info(be))
|
||||
static inline const char *backend_init(
|
||||
const BackendVtable *vt, Seat *seat, Backend **out, LogContext *logctx,
|
||||
Conf *conf, const char *host, int port, char **rhost, bool nd, bool ka)
|
||||
{ return vt->init(seat, out, logctx, conf, host, port, rhost, nd, ka); }
|
||||
static inline void backend_free(Backend *be)
|
||||
{ be->vt->free(be); }
|
||||
static inline void backend_reconfig(Backend *be, Conf *conf)
|
||||
{ be->vt->reconfig(be, conf); }
|
||||
static inline size_t backend_send(Backend *be, const char *buf, size_t len)
|
||||
{ return be->vt->send(be, buf, len); }
|
||||
static inline size_t backend_sendbuffer(Backend *be)
|
||||
{ return be->vt->sendbuffer(be); }
|
||||
static inline void backend_size(Backend *be, int width, int height)
|
||||
{ be->vt->size(be, width, height); }
|
||||
static inline void backend_special(
|
||||
Backend *be, SessionSpecialCode code, int arg)
|
||||
{ be->vt->special(be, code, arg); }
|
||||
static inline const SessionSpecial *backend_get_specials(Backend *be)
|
||||
{ return be->vt->get_specials(be); }
|
||||
static inline bool backend_connected(Backend *be)
|
||||
{ return be->vt->connected(be); }
|
||||
static inline int backend_exitcode(Backend *be)
|
||||
{ return be->vt->exitcode(be); }
|
||||
static inline bool backend_sendok(Backend *be)
|
||||
{ return be->vt->sendok(be); }
|
||||
static inline bool backend_ldisc_option_state(Backend *be, int state)
|
||||
{ return be->vt->ldisc_option_state(be, state); }
|
||||
static inline void backend_provide_ldisc(Backend *be, Ldisc *ldisc)
|
||||
{ be->vt->provide_ldisc(be, ldisc); }
|
||||
static inline void backend_unthrottle(Backend *be, size_t bufsize)
|
||||
{ be->vt->unthrottle(be, bufsize); }
|
||||
static inline int backend_cfg_info(Backend *be)
|
||||
{ return be->vt->cfg_info(be); }
|
||||
|
||||
extern const struct BackendVtable *const backends[];
|
||||
|
||||
@ -915,36 +931,44 @@ struct SeatVtable {
|
||||
bool (*get_window_pixel_size)(Seat *seat, int *width, int *height);
|
||||
};
|
||||
|
||||
#define seat_output(seat, is_stderr, data, len) \
|
||||
((seat)->vt->output(seat, is_stderr, data, len))
|
||||
#define seat_eof(seat) \
|
||||
((seat)->vt->eof(seat))
|
||||
#define seat_get_userpass_input(seat, p, input) \
|
||||
((seat)->vt->get_userpass_input(seat, p, input))
|
||||
#define seat_notify_remote_exit(seat) \
|
||||
((seat)->vt->notify_remote_exit(seat))
|
||||
#define seat_update_specials_menu(seat) \
|
||||
((seat)->vt->update_specials_menu(seat))
|
||||
#define seat_get_ttymode(seat, mode) \
|
||||
((seat)->vt->get_ttymode(seat, mode))
|
||||
#define seat_set_busy_status(seat, status) \
|
||||
((seat)->vt->set_busy_status(seat, status))
|
||||
#define seat_verify_ssh_host_key(seat, h, p, typ, str, fp, cb, ctx) \
|
||||
((seat)->vt->verify_ssh_host_key(seat, h, p, typ, str, fp, cb, ctx))
|
||||
#define seat_confirm_weak_crypto_primitive(seat, typ, alg, cb, ctx) \
|
||||
((seat)->vt->confirm_weak_crypto_primitive(seat, typ, alg, cb, ctx))
|
||||
#define seat_confirm_weak_cached_hostkey(seat, alg, better, cb, ctx) \
|
||||
((seat)->vt->confirm_weak_cached_hostkey(seat, alg, better, cb, ctx))
|
||||
#define seat_is_utf8(seat) \
|
||||
((seat)->vt->is_utf8(seat))
|
||||
#define seat_echoedit_update(seat, echoing, editing) \
|
||||
((seat)->vt->echoedit_update(seat, echoing, editing))
|
||||
#define seat_get_x_display(seat) \
|
||||
((seat)->vt->get_x_display(seat))
|
||||
#define seat_get_windowid(seat, out) \
|
||||
((seat)->vt->get_windowid(seat, out))
|
||||
#define seat_get_window_pixel_size(seat, width, height) \
|
||||
((seat)->vt->get_window_pixel_size(seat, width, height))
|
||||
static inline size_t seat_output(
|
||||
Seat *seat, bool err, const void *data, size_t len)
|
||||
{ return seat->vt->output(seat, err, data, len); }
|
||||
static inline bool seat_eof(Seat *seat)
|
||||
{ return seat->vt->eof(seat); }
|
||||
static inline int seat_get_userpass_input(
|
||||
Seat *seat, prompts_t *p, bufchain *input)
|
||||
{ return seat->vt->get_userpass_input(seat, p, input); }
|
||||
static inline void seat_notify_remote_exit(Seat *seat)
|
||||
{ seat->vt->notify_remote_exit(seat); }
|
||||
static inline void seat_update_specials_menu(Seat *seat)
|
||||
{ seat->vt->update_specials_menu(seat); }
|
||||
static inline char *seat_get_ttymode(Seat *seat, const char *mode)
|
||||
{ return seat->vt->get_ttymode(seat, mode); }
|
||||
static inline void seat_set_busy_status(Seat *seat, BusyStatus status)
|
||||
{ seat->vt->set_busy_status(seat, status); }
|
||||
static inline int seat_verify_ssh_host_key(
|
||||
Seat *seat, const char *h, int p, const char *ktyp, char *kstr,
|
||||
char *fp, void (*cb)(void *ctx, int result), void *ctx)
|
||||
{ return seat->vt->verify_ssh_host_key(seat, h, p, ktyp, kstr, fp, cb, ctx); }
|
||||
static inline int seat_confirm_weak_crypto_primitive(
|
||||
Seat *seat, const char *atyp, const char *aname,
|
||||
void (*cb)(void *ctx, int result), void *ctx)
|
||||
{ return seat->vt->confirm_weak_crypto_primitive(seat, atyp, aname, cb, ctx); }
|
||||
static inline int seat_confirm_weak_cached_hostkey(
|
||||
Seat *seat, const char *aname, const char *better,
|
||||
void (*cb)(void *ctx, int result), void *ctx)
|
||||
{ return seat->vt->confirm_weak_cached_hostkey(seat, aname, better, cb, ctx); }
|
||||
static inline bool seat_is_utf8(Seat *seat)
|
||||
{ return seat->vt->is_utf8(seat); }
|
||||
static inline void seat_echoedit_update(Seat *seat, bool ec, bool ed)
|
||||
{ seat->vt->echoedit_update(seat, ec, ed); }
|
||||
static inline const char *seat_get_x_display(Seat *seat)
|
||||
{ return seat->vt->get_x_display(seat); }
|
||||
static inline bool seat_get_windowid(Seat *seat, long *id_out)
|
||||
{ return seat->vt->get_windowid(seat, id_out); }
|
||||
static inline bool seat_get_window_pixel_size(Seat *seat, int *w, int *h)
|
||||
{ return seat->vt->get_window_pixel_size(seat, w, h); }
|
||||
|
||||
/* Unlike the seat's actual method, the public entry point
|
||||
* seat_connection_fatal is a wrapper function with a printf-like API,
|
||||
@ -952,10 +976,10 @@ struct SeatVtable {
|
||||
void seat_connection_fatal(Seat *seat, const char *fmt, ...);
|
||||
|
||||
/* Handy aliases for seat_output which set is_stderr to a fixed value. */
|
||||
#define seat_stdout(seat, data, len) \
|
||||
seat_output(seat, false, data, len)
|
||||
#define seat_stderr(seat, data, len) \
|
||||
seat_output(seat, true, data, len)
|
||||
static inline size_t seat_stdout(Seat *seat, const void *data, size_t len)
|
||||
{ return seat_output(seat, false, data, len); }
|
||||
static inline size_t seat_stderr(Seat *seat, const void *data, size_t len)
|
||||
{ return seat_output(seat, true, data, len); }
|
||||
|
||||
/*
|
||||
* Stub methods for seat implementations that want to use the obvious
|
||||
@ -1083,60 +1107,66 @@ struct TermWinVtable {
|
||||
bool (*is_utf8)(TermWin *);
|
||||
};
|
||||
|
||||
#define win_setup_draw_ctx(win) \
|
||||
((win)->vt->setup_draw_ctx(win))
|
||||
#define win_draw_text(win, x, y, text, len, attrs, lattrs, tc) \
|
||||
((win)->vt->draw_text(win, x, y, text, len, attrs, lattrs, tc))
|
||||
#define win_draw_cursor(win, x, y, text, len, attrs, lattrs, tc) \
|
||||
((win)->vt->draw_cursor(win, x, y, text, len, attrs, lattrs, tc))
|
||||
#define win_char_width(win, uc) \
|
||||
((win)->vt->char_width(win, uc))
|
||||
#define win_free_draw_ctx(win) \
|
||||
((win)->vt->free_draw_ctx(win))
|
||||
#define win_set_cursor_pos(win, x, y) \
|
||||
((win)->vt->set_cursor_pos(win, x, y))
|
||||
#define win_set_raw_mouse_mode(win, enable) \
|
||||
((win)->vt->set_raw_mouse_mode(win, enable))
|
||||
#define win_set_scrollbar(win, total, start, page) \
|
||||
((win)->vt->set_scrollbar(win, total, start, page))
|
||||
#define win_bell(win, mode) \
|
||||
((win)->vt->bell(win, mode))
|
||||
#define win_clip_write(win, clipboard, text, attrs, colours, len, desel) \
|
||||
((win)->vt->clip_write(win, clipboard, text, attrs, colours, len, desel))
|
||||
#define win_clip_request_paste(win, clipboard) \
|
||||
((win)->vt->clip_request_paste(win, clipboard))
|
||||
#define win_refresh(win) \
|
||||
((win)->vt->refresh(win))
|
||||
#define win_request_resize(win, w, h) \
|
||||
((win)->vt->request_resize(win, w, h))
|
||||
#define win_set_title(win, title) \
|
||||
((win)->vt->set_title(win, title))
|
||||
#define win_set_icon_title(win, ititle) \
|
||||
((win)->vt->set_icon_title(win, ititle))
|
||||
#define win_set_minimised(win, minimised) \
|
||||
((win)->vt->set_minimised(win, minimised))
|
||||
#define win_is_minimised(win) \
|
||||
((win)->vt->is_minimised(win))
|
||||
#define win_set_maximised(win, maximised) \
|
||||
((win)->vt->set_maximised(win, maximised))
|
||||
#define win_move(win, x, y) \
|
||||
((win)->vt->move(win, x, y))
|
||||
#define win_set_zorder(win, top) \
|
||||
((win)->vt->set_zorder(win, top))
|
||||
#define win_palette_get(win, n, r, g, b) \
|
||||
((win)->vt->palette_get(win, n, r, g, b))
|
||||
#define win_palette_set(win, n, r, g, b) \
|
||||
((win)->vt->palette_set(win, n, r, g, b))
|
||||
#define win_palette_reset(win) \
|
||||
((win)->vt->palette_reset(win))
|
||||
#define win_get_pos(win, x, y) \
|
||||
((win)->vt->get_pos(win, x, y))
|
||||
#define win_get_pixels(win, x, y) \
|
||||
((win)->vt->get_pixels(win, x, y))
|
||||
#define win_get_title(win, icon) \
|
||||
((win)->vt->get_title(win, icon))
|
||||
#define win_is_utf8(win) \
|
||||
((win)->vt->is_utf8(win))
|
||||
static inline bool win_setup_draw_ctx(TermWin *win)
|
||||
{ return win->vt->setup_draw_ctx(win); }
|
||||
static inline void win_draw_text(
|
||||
TermWin *win, int x, int y, wchar_t *text, int len,
|
||||
unsigned long attrs, int line_attrs, truecolour tc)
|
||||
{ win->vt->draw_text(win, x, y, text, len, attrs, line_attrs, tc); }
|
||||
static inline void win_draw_cursor(
|
||||
TermWin *win, int x, int y, wchar_t *text, int len,
|
||||
unsigned long attrs, int line_attrs, truecolour tc)
|
||||
{ win->vt->draw_cursor(win, x, y, text, len, attrs, line_attrs, tc); }
|
||||
static inline int win_char_width(TermWin *win, int uc)
|
||||
{ return win->vt->char_width(win, uc); }
|
||||
static inline void win_free_draw_ctx(TermWin *win)
|
||||
{ win->vt->free_draw_ctx(win); }
|
||||
static inline void win_set_cursor_pos(TermWin *win, int x, int y)
|
||||
{ win->vt->set_cursor_pos(win, x, y); }
|
||||
static inline void win_set_raw_mouse_mode(TermWin *win, bool enable)
|
||||
{ win->vt->set_raw_mouse_mode(win, enable); }
|
||||
static inline void win_set_scrollbar(TermWin *win, int t, int s, int p)
|
||||
{ win->vt->set_scrollbar(win, t, s, p); }
|
||||
static inline void win_bell(TermWin *win, int mode)
|
||||
{ win->vt->bell(win, mode); }
|
||||
static inline void win_clip_write(
|
||||
TermWin *win, int clipboard, wchar_t *text, int *attrs,
|
||||
truecolour *colours, int len, bool deselect)
|
||||
{ win->vt->clip_write(win, clipboard, text, attrs, colours, len, deselect); }
|
||||
static inline void win_clip_request_paste(TermWin *win, int clipboard)
|
||||
{ win->vt->clip_request_paste(win, clipboard); }
|
||||
static inline void win_refresh(TermWin *win)
|
||||
{ win->vt->refresh(win); }
|
||||
static inline void win_request_resize(TermWin *win, int w, int h)
|
||||
{ win->vt->request_resize(win, w, h); }
|
||||
static inline void win_set_title(TermWin *win, const char *title)
|
||||
{ win->vt->set_title(win, title); }
|
||||
static inline void win_set_icon_title(TermWin *win, const char *icontitle)
|
||||
{ win->vt->set_icon_title(win, icontitle); }
|
||||
static inline void win_set_minimised(TermWin *win, bool minimised)
|
||||
{ win->vt->set_minimised(win, minimised); }
|
||||
static inline bool win_is_minimised(TermWin *win)
|
||||
{ return win->vt->is_minimised(win); }
|
||||
static inline void win_set_maximised(TermWin *win, bool maximised)
|
||||
{ win->vt->set_maximised(win, maximised); }
|
||||
static inline void win_move(TermWin *win, int x, int y)
|
||||
{ win->vt->move(win, x, y); }
|
||||
static inline void win_set_zorder(TermWin *win, bool top)
|
||||
{ win->vt->set_zorder(win, top); }
|
||||
static inline bool win_palette_get(TermWin *win, int n, int *r, int *g, int *b)
|
||||
{ return win->vt->palette_get(win, n, r, g, b); }
|
||||
static inline void win_palette_set(TermWin *win, int n, int r, int g, int b)
|
||||
{ win->vt->palette_set(win, n, r, g, b); }
|
||||
static inline void win_palette_reset(TermWin *win)
|
||||
{ win->vt->palette_reset(win); }
|
||||
static inline void win_get_pos(TermWin *win, int *x, int *y)
|
||||
{ win->vt->get_pos(win, x, y); }
|
||||
static inline void win_get_pixels(TermWin *win, int *x, int *y)
|
||||
{ win->vt->get_pixels(win, x, y); }
|
||||
static inline const char *win_get_title(TermWin *win, bool icon)
|
||||
{ return win->vt->get_title(win, icon); }
|
||||
static inline bool win_is_utf8(TermWin *win)
|
||||
{ return win->vt->is_utf8(win); }
|
||||
|
||||
/*
|
||||
* Global functions not specific to a connection instance.
|
||||
@ -1606,9 +1636,15 @@ struct LogPolicyVtable {
|
||||
struct LogPolicy {
|
||||
const LogPolicyVtable *vt;
|
||||
};
|
||||
#define lp_eventlog(lp, event) ((lp)->vt->eventlog(lp, event))
|
||||
#define lp_askappend(lp, fn, cb, ctx) ((lp)->vt->askappend(lp, fn, cb, ctx))
|
||||
#define lp_logging_error(lp, event) ((lp)->vt->logging_error(lp, event))
|
||||
|
||||
static inline void lp_eventlog(LogPolicy *lp, const char *event)
|
||||
{ lp->vt->eventlog(lp, event); }
|
||||
static inline int lp_askappend(
|
||||
LogPolicy *lp, Filename *filename,
|
||||
void (*callback)(void *ctx, int result), void *ctx)
|
||||
{ return lp->vt->askappend(lp, filename, callback, ctx); }
|
||||
static inline void lp_logging_error(LogPolicy *lp, const char *event)
|
||||
{ lp->vt->logging_error(lp, event); }
|
||||
|
||||
LogContext *log_init(LogPolicy *lp, Conf *conf);
|
||||
void log_free(LogContext *logctx);
|
||||
|
Reference in New Issue
Block a user