tacme: Apply each -/+ only once (#156) - plan9port - [fork] Plan 9 from user space
 (HTM) git clone git://src.adamsgaard.dk/plan9port
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit a82a8b6368274d77d42f526e379b74e79c137e26
 (DIR) parent df2d9ec9d169626cdc2a23829bb2831738215722
 (HTM) Author: Martin Kühl <martin.kuehl@gmail.com>
       Date:   Wed, 19 Sep 2018 15:19:36 +0200
       
       acme: Apply each -/+ only once (#156)
       
       When plumbing an address like `3-`, Acme selects line 1,
       and similarly `3+` selects line 5.
       The same problem can be observed for character addresses (`#123+`)
       but _not_ for ones like `+`, `.+` or `/foo/+`:
       The problem only occurs when a number is followed by a direction (`-`/`+`).
       
       Following along with the example `3-` through `address` (in addr.c):
       We read `3` into `c` and match the `case` on line 239.
       The `while` loop on line 242ff reads additional digits into `c`
       and puts the first non-digit back by decrementing the index `q`.
       Then we find the range for line 3 on line 251 and continue.
       
       On the next iteration, we set `prevc` to the last `c`,
       but since that part read ahead _into `c`_,
       `c` is currently the _next_ character we will read, `-`,
       and now `prevc` is too.
       
       Then in the case block (line 210) the condition on line 211 holds
       and Acme believes that it has read two `-` in sequence
       and modifies the range to account for the “first” `-`.
       The “second” `-` gets applied after the loop is done, on line 292.
       
       So the general problem is:
       While reading numbers, Acme reads the next character after the number into `c`.
       It decrements the counter to ensure it will read it again on the next iteration,
       but it still uses it to update `prevc`.
       
       This change solves the problem by reading digits into `nc` instead.
       This variable is used to similar effect in the block for directions (line 212)
       and fills the role of “local `c` that we can safely use to read ahead” nicely.
       Diffstat:
         M src/cmd/acme/addr.c                 |       6 +++---
       
       1 file changed, 3 insertions(+), 3 deletions(-)
       ---
 (DIR) diff --git a/src/cmd/acme/addr.c b/src/cmd/acme/addr.c
       t@@ -240,12 +240,12 @@ address(uint showerr, Text *t, Range lim, Range ar, void *a, uint q0, uint q1, i
                        case '5': case '6': case '7': case '8': case '9':
                                n = c -'0';
                                while(q<q1){
       -                                c = (*getc)(a, q++);
       -                                if(c<'0' || '9'<c){
       +                                nc = (*getc)(a, q++);
       +                                if(nc<'0' || '9'<nc){
                                                q--;
                                                break;
                                        }
       -                                n = n*10+(c-'0');
       +                                n = n*10+(nc-'0');
                                }
                                if(*evalp)
                                        r = number(showerr, t, r, n, dir, size, evalp);