From c713ce4868bde0283c348dbc0f138dc3b93517a8 Mon Sep 17 00:00:00 2001 From: Simon Tatham Date: Tue, 23 Jul 2019 19:16:36 +0100 Subject: [PATCH] terminal.[ch]: refactor the 'pos' macros. These are now inline functions (mostly, except for a couple of macro wrappers to preserve the old call syntax), and they live in terminal.h instead of at the top of terminal.c. Also, I've added a few comments for clarity, and renamed the posPlt() function, which didn't do at all what the name made it look (at least to a mathematician familiar with product orders) as if it did. --- terminal.c | 18 +---------- terminal.h | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 91 insertions(+), 17 deletions(-) diff --git a/terminal.c b/terminal.c index 968bc12d..c1a12c04 100644 --- a/terminal.c +++ b/terminal.c @@ -13,22 +13,6 @@ #include "putty.h" #include "terminal.h" -#define poslt(p1,p2) ( (p1).y < (p2).y || ( (p1).y == (p2).y && (p1).x < (p2).x ) ) -#define posle(p1,p2) ( (p1).y < (p2).y || ( (p1).y == (p2).y && (p1).x <= (p2).x ) ) -#define poseq(p1,p2) ( (p1).y == (p2).y && (p1).x == (p2).x ) -#define posdiff(p1,p2) ( ((p1).y - (p2).y) * (term->cols+1) + (p1).x - (p2).x ) - -/* Product-order comparisons for rectangular block selection. */ -#define posPlt(p1,p2) ( (p1).y <= (p2).y && (p1).x < (p2).x ) -#define posPle(p1,p2) ( (p1).y <= (p2).y && (p1).x <= (p2).x ) - -#define incpos(p) ( (p).x == term->cols ? \ - ((p).x = 0, (p).y++, true) : \ - ((p).x++, false) ) -#define decpos(p) ( (p).x == 0 ? \ - ((p).x = term->cols, (p).y--, true) : \ - ((p).x--, false) ) - #define VT52_PLUS #define CL_ANSIMIN 0x0001 /* Codes in all ANSI like terminals. */ @@ -5492,7 +5476,7 @@ static void do_paint(Terminal *term) poslt(scrpos, term->selend)); else selected = (posPle(term->selstart, scrpos) && - posPlt(scrpos, term->selend)); + posPle_left(scrpos, term->selend)); } else selected = false; tattr = (tattr ^ rv diff --git a/terminal.h b/terminal.h index 23c91e1f..1ed0b17d 100644 --- a/terminal.h +++ b/terminal.h @@ -385,4 +385,94 @@ static inline int term_char_width(Terminal *term, unsigned int c) */ #define CC_LIMIT 32 +/* ---------------------------------------------------------------------- + * Helper functions for dealing with the small 'pos' structure. + */ + +static inline bool poslt(pos p1, pos p2) +{ + if (p1.y != p2.y) + return p1.y < p2.y; + return p1.x < p2.x; +} + +static inline bool posle(pos p1, pos p2) +{ + if (p1.y != p2.y) + return p1.y < p2.y; + return p1.x <= p2.x; +} + +static inline bool poseq(pos p1, pos p2) +{ + return p1.y == p2.y && p1.x == p2.x; +} + +static inline int posdiff_fn(pos p1, pos p2, int cols) +{ + return (p1.y - p2.y) * (cols+1) + (p1.x - p2.x); +} + +/* Convenience wrapper on posdiff_fn which uses the 'Terminal *term' + * that more or less every function in terminal.c will have in scope. + * For safety's sake I include a TYPECHECK that ensures it really is a + * structure pointer of the right type. */ +#define GET_TERM_COLS TYPECHECK(term == (Terminal *)0, term->cols) +#define posdiff(p1,p2) posdiff_fn(p1, p2, GET_TERM_COLS) + +/* Product-order comparisons for rectangular block selection. */ + +static inline bool posPle(pos p1, pos p2) +{ + return p1.y <= p2.y && p1.x <= p2.x; +} + +static inline bool posPle_left(pos p1, pos p2) +{ + /* + * This function is used for checking whether a given character + * cell of the terminal ought to be highlighted as part of the + * selection, by comparing with term->selend. term->selend stores + * the location one space to the right of the last highlighted + * character. So we want to highlight the characters that are + * less-or-equal (in the product order) to the character just left + * of p2. + * + * (Setting up term->selend that way was the easiest way to get + * rectangular selection working at all, in a code base that had + * done lexicographic selection the way I happened to have done + * it.) + */ + return p1.y <= p2.y && p1.x < p2.x; +} + +static inline bool incpos_fn(pos *p, int cols) +{ + if (p->x == cols) { + p->x = 0; + p->y++; + return true; + } + p->x++; + return false; +} + +static inline bool decpos_fn(pos *p, int cols) +{ + if (p->x == 0) { + p->x = cols; + p->y--; + return true; + } + p->x--; + return false; +} + +/* Convenience wrappers on incpos and decpos which use term->cols + * (similarly to posdiff above), and also (for mild convenience and + * mostly historical inertia) let you leave off the & at every call + * site. */ +#define incpos(p) incpos_fn(&(p), GET_TERM_COLS) +#define decpos(p) decpos_fn(&(p), GET_TERM_COLS) + #endif