diff options
author | Martin Kühl <martin.kuehl@gmail.com> | 2018-09-19 15:19:36 +0200 |
---|---|---|
committer | Rob Pike <r@golang.org> | 2018-09-19 23:19:36 +1000 |
commit | a82a8b6368274d77d42f526e379b74e79c137e26 (patch) | |
tree | fc99eb987e6a0bb0fd818692321e1f655ca49fe8 /src/cmd/acme | |
parent | df2d9ec9d169626cdc2a23829bb2831738215722 (diff) | |
download | plan9port-a82a8b6368274d77d42f526e379b74e79c137e26.tar.gz plan9port-a82a8b6368274d77d42f526e379b74e79c137e26.tar.bz2 plan9port-a82a8b6368274d77d42f526e379b74e79c137e26.zip |
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 (limited to 'src/cmd/acme')
-rw-r--r-- | src/cmd/acme/addr.c | 6 |
1 files changed, 3 insertions, 3 deletions
diff --git a/src/cmd/acme/addr.c b/src/cmd/acme/addr.c index 2ccae960..6aee8993 100644 --- a/src/cmd/acme/addr.c +++ b/src/cmd/acme/addr.c @@ -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); |