From 2b21a98e9c0e842bd2a66e18ff82b952a494e75c Mon Sep 17 00:00:00 2001 From: Renaud Fivet Date: Thu, 19 May 2016 21:27:26 +0800 Subject: [PATCH] Review forwchar and backchar. --- ebind.c | 14 +++++----- line.c | 83 +++++++++++++++++++++++++++++--------------------------- line.h | 4 +-- names.c | 4 +-- random.c | 2 +- 5 files changed, 55 insertions(+), 52 deletions(-) diff --git a/ebind.c b/ebind.c index f3a2ad9..aba7853 100644 --- a/ebind.c +++ b/ebind.c @@ -37,7 +37,7 @@ struct key_tab keytab[NBINDS] = { {CONTROL | 'A', gotobol} , - {CONTROL | 'B', backchar} + {CONTROL | 'B', (fn_t) backchar} , {CONTROL | 'C', insspace} , @@ -45,7 +45,7 @@ struct key_tab keytab[NBINDS] = { , {CONTROL | 'E', gotoeol} , - {CONTROL | 'F', forwchar} + {CONTROL | 'F', (fn_t) forwchar} , {CONTROL | 'G', ctrlg} , @@ -329,9 +329,9 @@ struct key_tab keytab[NBINDS] = { , {SPEC | 73, backpage} , - {SPEC | 75, backchar} + {SPEC | 75, (fn_t) backchar} , - {SPEC | 77, forwchar} + {SPEC | 77, (fn_t) forwchar} , {SPEC | 79, gotoeol} , @@ -406,13 +406,13 @@ struct key_tab keytab[NBINDS] = { , {SPEC | 'B', forwline} , - {SPEC | 'C', forwchar} + {SPEC | 'C', (fn_t) forwchar} , - {SPEC | 'D', backchar} + {SPEC | 'D', (fn_t) backchar} , {SPEC | 'c', metafn} , - {SPEC | 'd', backchar} + {SPEC | 'd', (fn_t) backchar} , {SPEC | 'e', forwline} , diff --git a/line.c b/line.c index f3c59a0..f085b8c 100644 --- a/line.c +++ b/line.c @@ -91,16 +91,38 @@ char *getkill( void) { * location. Error if you try and move out of the buffer. Set the flag if the * line pointer for dot changes. */ -int backchar( int f, int n) { +static unsigned utf8_revdelta( unsigned char *p, unsigned pos) { + unsigned delta = 0 ; + + if( (*p & 0xC0) == 0x80) { + unsigned char c ; + + c = *--p ; + if( (c & 0xE0) == 0xC0) /* valid 2 bytes unicode seq */ + delta = 1 ; + else if( ((c & 0xC0) == 0x80) && (pos > 1)) { + c = *--p ; + if( (c & 0xF0) == 0xE0) /* valid 3 bytes unicode seq */ + delta = 2 ; + else if( ((c & 0xC0) == 0x80) && (pos > 2)) + if( (p[ -1] & 0xF8) == 0xF0) /* valid 4 bytes unicode seq */ + delta = 3 ; + } + } + + return delta ; +} + +boolean backchar( int f, int n) { if( n < 0) return forwchar( f, -n) ; while( n--) { - if( curwp->w_doto == 0) { - struct line *lp ; + if( curwp->w_doto == 0) { /* at beginning of line */ + line_p lp ; lp = lback( curwp->w_dotp) ; - if( lp == curbp->b_linep) + if( lp == curbp->b_linep) /* at beginning of buffer */ return FALSE ; curwp->w_dotp = lp ; @@ -110,29 +132,8 @@ int backchar( int f, int n) { unsigned pos ; pos = curwp->w_doto -= 1 ; - if( pos > 0) { - unsigned char *p ; - - p = (unsigned char *) &( (curwp->w_dotp)->l_text[ pos]) ; - if( (*p & 0xC0) == 0x80) { - unsigned char c ; - int delta = 0 ; - - c = *--p ; - if( (c & 0xE0) == 0xC0) /* valid 2 bytes unicode seq */ - delta = 1 ; - else if( ((c & 0xC0) == 0x80) && (pos > 1)) { - c = *--p ; - if( (c & 0xF0) == 0xE0) /* valid 3 bytes unicode seq */ - delta = 2 ; - else if( ((c & 0xC0) == 0x80) && (pos > 2)) - if( (p[ -1] & 0xF8) == 0xF0) /* valid 4 bytes unicode seq */ - delta = 3 ; - } - - curwp->w_doto -= delta ; - } - } + if( pos > 0) + curwp->w_doto -= utf8_revdelta( (unsigned char *) &( (curwp->w_dotp)->l_text[ pos]), pos) ; } } @@ -145,18 +146,19 @@ int backchar( int f, int n) { * location, and move ".". Error if you try and move off the end of the * buffer. Set the flag if the line pointer for dot changes. */ -int forwchar(int f, int n) -{ - if (n < 0) - return backchar(f, -n); - while (n--) { - int len = llength(curwp->w_dotp); - if (curwp->w_doto == len) { - if (curwp->w_dotp == curbp->b_linep) - return FALSE; - curwp->w_dotp = lforw(curwp->w_dotp); - curwp->w_doto = 0; - curwp->w_flag |= WFMOVE; +boolean forwchar( int f, int n) { + if( n < 0) + return backchar( f, -n) ; + + while( n--) { + int len = llength( curwp->w_dotp) ; + if( curwp->w_doto == len) { /* at end of line */ + if( curwp->w_dotp == curbp->b_linep) /* at end of buffer */ + return FALSE ; + + curwp->w_dotp = lforw( curwp->w_dotp) ; + curwp->w_doto = 0 ; + curwp->w_flag |= WFMOVE ; } else { unicode_t unc ; unsigned bytes ; @@ -165,7 +167,8 @@ int forwchar(int f, int n) curwp->w_doto += bytes ; } } - return TRUE; + + return TRUE ; } /* diff --git a/line.h b/line.h index e082e1d..fb88741 100644 --- a/line.h +++ b/line.h @@ -30,8 +30,8 @@ extern int tabwidth ; /* Map to $tab, default to 8, can be set to [1, .. */ char *getkill( void) ; -int backchar( int f, int n) ; -int forwchar( int f, int n) ; +boolean backchar( int f, int n) ; +boolean forwchar( int f, int n) ; void lfree( line_p lp) ; void lchange( int flag) ; diff --git a/names.c b/names.c index ea6b22b..f44bfb7 100644 --- a/names.c +++ b/names.c @@ -34,7 +34,7 @@ struct name_bind names[] = { #if APROP {"apropos", apro}, #endif - {"backward-character", backchar}, + {"backward-character", (fn_t) backchar}, {"begin-macro", ctlxlp}, {"beginning-of-file", gotobob}, {"beginning-of-line", gotobol}, @@ -132,7 +132,7 @@ struct name_bind names[] = { #endif {"filter-buffer", filter_buffer}, {"find-file", filefind}, - {"forward-character", forwchar}, + {"forward-character", (fn_t) forwchar}, {"goto-line", gotoline}, #if CFENCE {"goto-matching-fence", getfence}, diff --git a/random.c b/random.c index 70eabb7..d0e239f 100644 --- a/random.c +++ b/random.c @@ -705,7 +705,7 @@ int backdel( int f, int n) { thisflag |= CFKILL; } - return (backchar( f, n) == TRUE) && ldelchar( n, f != FALSE) ; + return backchar( f, n) && ldelchar( n, f != FALSE) ; } /*