diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2008-10-26 16:30:09 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2008-10-26 16:30:09 +0000 |
commit | e1ef89abada09b96fb79b167c5d60db718f9429e (patch) | |
tree | 5d89405ba67b43d2bf49da791a6aef29bb2ce370 /miscutils/less.c | |
parent | c94fa5651a6c4f6b526de261e7480ce2c4e34aba (diff) | |
download | busybox-w32-e1ef89abada09b96fb79b167c5d60db718f9429e.tar.gz busybox-w32-e1ef89abada09b96fb79b167c5d60db718f9429e.tar.bz2 busybox-w32-e1ef89abada09b96fb79b167c5d60db718f9429e.zip |
less: correctly wrap lines with tabs
Diffstat (limited to 'miscutils/less.c')
-rw-r--r-- | miscutils/less.c | 54 |
1 files changed, 27 insertions, 27 deletions
diff --git a/miscutils/less.c b/miscutils/less.c index 4f00fadb5..68b7c6c0c 100644 --- a/miscutils/less.c +++ b/miscutils/less.c | |||
@@ -65,7 +65,7 @@ struct globals { | |||
65 | int kbd_fd; /* fd to get input from */ | 65 | int kbd_fd; /* fd to get input from */ |
66 | int less_gets_pos; | 66 | int less_gets_pos; |
67 | /* last position in last line, taking into account tabs */ | 67 | /* last position in last line, taking into account tabs */ |
68 | size_t linepos; | 68 | size_t last_line_pos; |
69 | unsigned max_fline; | 69 | unsigned max_fline; |
70 | unsigned max_lineno; /* this one tracks linewrap */ | 70 | unsigned max_lineno; /* this one tracks linewrap */ |
71 | unsigned max_displayed_line; | 71 | unsigned max_displayed_line; |
@@ -102,7 +102,7 @@ struct globals { | |||
102 | #define cur_fline (G.cur_fline ) | 102 | #define cur_fline (G.cur_fline ) |
103 | #define kbd_fd (G.kbd_fd ) | 103 | #define kbd_fd (G.kbd_fd ) |
104 | #define less_gets_pos (G.less_gets_pos ) | 104 | #define less_gets_pos (G.less_gets_pos ) |
105 | #define linepos (G.linepos ) | 105 | #define last_line_pos (G.last_line_pos ) |
106 | #define max_fline (G.max_fline ) | 106 | #define max_fline (G.max_fline ) |
107 | #define max_lineno (G.max_lineno ) | 107 | #define max_lineno (G.max_lineno ) |
108 | #define max_displayed_line (G.max_displayed_line) | 108 | #define max_displayed_line (G.max_displayed_line) |
@@ -197,7 +197,7 @@ static void less_exit(int code) | |||
197 | static void re_wrap(void) | 197 | static void re_wrap(void) |
198 | { | 198 | { |
199 | int w = width; | 199 | int w = width; |
200 | int rem; | 200 | int new_line_pos; |
201 | int src_idx; | 201 | int src_idx; |
202 | int dst_idx; | 202 | int dst_idx; |
203 | int new_cur_fline = 0; | 203 | int new_cur_fline = 0; |
@@ -216,14 +216,16 @@ static void re_wrap(void) | |||
216 | s = old_flines[0]; | 216 | s = old_flines[0]; |
217 | lineno = LINENO(s); | 217 | lineno = LINENO(s); |
218 | d = linebuf; | 218 | d = linebuf; |
219 | rem = w; | 219 | new_line_pos = 0; |
220 | while (1) { | 220 | while (1) { |
221 | *d = *s; | 221 | *d = *s; |
222 | if (*d != '\0') { | 222 | if (*d != '\0') { |
223 | new_line_pos++; | ||
224 | if (*d == '\t') /* tab */ | ||
225 | new_line_pos += 7; | ||
223 | s++; | 226 | s++; |
224 | d++; | 227 | d++; |
225 | rem--; | 228 | if (new_line_pos >= w) { |
226 | if (rem == 0) { | ||
227 | int sz; | 229 | int sz; |
228 | /* new line is full, create next one */ | 230 | /* new line is full, create next one */ |
229 | *d = '\0'; | 231 | *d = '\0'; |
@@ -235,28 +237,26 @@ static void re_wrap(void) | |||
235 | new_flines = xrealloc_vector(new_flines, 8, dst_idx); | 237 | new_flines = xrealloc_vector(new_flines, 8, dst_idx); |
236 | new_flines[dst_idx] = d; | 238 | new_flines[dst_idx] = d; |
237 | dst_idx++; | 239 | dst_idx++; |
238 | if (rem) { | 240 | if (new_line_pos < w) { |
239 | /* did we come here thru "goto next_new"? */ | 241 | /* if we came here thru "goto next_new" */ |
240 | if (src_idx > max_fline) | 242 | if (src_idx > max_fline) |
241 | break; | 243 | break; |
242 | lineno = LINENO(s); | 244 | lineno = LINENO(s); |
243 | } | 245 | } |
244 | d = linebuf; | 246 | d = linebuf; |
245 | rem = w; | 247 | new_line_pos = 0; |
246 | } | 248 | } |
247 | continue; | 249 | continue; |
248 | } | 250 | } |
249 | /* *d == NUL: old line ended, go to next old one */ | 251 | /* *d == NUL: old line ended, go to next old one */ |
250 | free(MEMPTR(old_flines[src_idx])); | 252 | free(MEMPTR(old_flines[src_idx])); |
251 | /* btw, convert cur_fline... */ | 253 | /* btw, convert cur_fline... */ |
252 | if (cur_fline == src_idx) { | 254 | if (cur_fline == src_idx) |
253 | new_cur_fline = dst_idx; | 255 | new_cur_fline = dst_idx; |
254 | } | ||
255 | src_idx++; | 256 | src_idx++; |
256 | /* no more lines? finish last new line (and exit the loop) */ | 257 | /* no more lines? finish last new line (and exit the loop) */ |
257 | if (src_idx > max_fline) { | 258 | if (src_idx > max_fline) |
258 | goto next_new; | 259 | goto next_new; |
259 | } | ||
260 | s = old_flines[src_idx]; | 260 | s = old_flines[src_idx]; |
261 | if (lineno != LINENO(s)) { | 261 | if (lineno != LINENO(s)) { |
262 | /* this is not a continuation line! | 262 | /* this is not a continuation line! |
@@ -269,7 +269,7 @@ static void re_wrap(void) | |||
269 | flines = (const char **)new_flines; | 269 | flines = (const char **)new_flines; |
270 | 270 | ||
271 | max_fline = dst_idx - 1; | 271 | max_fline = dst_idx - 1; |
272 | linepos = 0; // XXX | 272 | last_line_pos = new_line_pos; |
273 | cur_fline = new_cur_fline; | 273 | cur_fline = new_cur_fline; |
274 | /* max_lineno is screen-size independent */ | 274 | /* max_lineno is screen-size independent */ |
275 | pattern_valid = 0; | 275 | pattern_valid = 0; |
@@ -301,7 +301,7 @@ static void fill_match_lines(unsigned pos); | |||
301 | * on line wrap, only on "real" new lines. | 301 | * on line wrap, only on "real" new lines. |
302 | * readbuf[0..readeof-1] - small preliminary buffer. | 302 | * readbuf[0..readeof-1] - small preliminary buffer. |
303 | * readbuf[readpos] - next character to add to current line. | 303 | * readbuf[readpos] - next character to add to current line. |
304 | * linepos - screen line position of next char to be read | 304 | * last_line_pos - screen line position of next char to be read |
305 | * (takes into account tabs and backspaces) | 305 | * (takes into account tabs and backspaces) |
306 | * eof_error - < 0 error, == 0 EOF, > 0 not EOF/error | 306 | * eof_error - < 0 error, == 0 EOF, > 0 not EOF/error |
307 | */ | 307 | */ |
@@ -329,9 +329,9 @@ static void read_lines(void) | |||
329 | strcpy(p, cp); | 329 | strcpy(p, cp); |
330 | p += strlen(current_line); | 330 | p += strlen(current_line); |
331 | free(MEMPTR(flines[max_fline])); | 331 | free(MEMPTR(flines[max_fline])); |
332 | /* linepos is still valid from previous read_lines() */ | 332 | /* last_line_pos is still valid from previous read_lines() */ |
333 | } else { | 333 | } else { |
334 | linepos = 0; | 334 | last_line_pos = 0; |
335 | } | 335 | } |
336 | 336 | ||
337 | while (1) { /* read lines until we reach cur_fline or wanted_match */ | 337 | while (1) { /* read lines until we reach cur_fline or wanted_match */ |
@@ -353,28 +353,28 @@ static void read_lines(void) | |||
353 | /* backspace? [needed for manpages] */ | 353 | /* backspace? [needed for manpages] */ |
354 | /* <tab><bs> is (a) insane and */ | 354 | /* <tab><bs> is (a) insane and */ |
355 | /* (b) harder to do correctly, so we refuse to do it */ | 355 | /* (b) harder to do correctly, so we refuse to do it */ |
356 | if (c == '\x8' && linepos && p[-1] != '\t') { | 356 | if (c == '\x8' && last_line_pos && p[-1] != '\t') { |
357 | readpos++; /* eat it */ | 357 | readpos++; /* eat it */ |
358 | linepos--; | 358 | last_line_pos--; |
359 | /* was buggy (p could end up <= current_line)... */ | 359 | /* was buggy (p could end up <= current_line)... */ |
360 | *--p = '\0'; | 360 | *--p = '\0'; |
361 | continue; | 361 | continue; |
362 | } | 362 | } |
363 | { | 363 | { |
364 | size_t new_linepos = linepos + 1; | 364 | size_t new_last_line_pos = last_line_pos + 1; |
365 | if (c == '\t') { | 365 | if (c == '\t') { |
366 | new_linepos += 7; | 366 | new_last_line_pos += 7; |
367 | new_linepos &= (~7); | 367 | new_last_line_pos &= (~7); |
368 | } | 368 | } |
369 | if ((int)new_linepos >= w) | 369 | if ((int)new_last_line_pos >= w) |
370 | break; | 370 | break; |
371 | linepos = new_linepos; | 371 | last_line_pos = new_last_line_pos; |
372 | } | 372 | } |
373 | /* ok, we will eat this char */ | 373 | /* ok, we will eat this char */ |
374 | readpos++; | 374 | readpos++; |
375 | if (c == '\n') { | 375 | if (c == '\n') { |
376 | terminated = 1; | 376 | terminated = 1; |
377 | linepos = 0; | 377 | last_line_pos = 0; |
378 | break; | 378 | break; |
379 | } | 379 | } |
380 | /* NUL is substituted by '\n'! */ | 380 | /* NUL is substituted by '\n'! */ |
@@ -449,7 +449,7 @@ static void read_lines(void) | |||
449 | max_fline++; | 449 | max_fline++; |
450 | current_line = ((char*)xmalloc(w + 4)) + 4; | 450 | current_line = ((char*)xmalloc(w + 4)) + 4; |
451 | p = current_line; | 451 | p = current_line; |
452 | linepos = 0; | 452 | last_line_pos = 0; |
453 | } /* end of "read lines until we reach cur_fline" loop */ | 453 | } /* end of "read lines until we reach cur_fline" loop */ |
454 | fill_match_lines(old_max_fline); | 454 | fill_match_lines(old_max_fline); |
455 | #if ENABLE_FEATURE_LESS_REGEXP | 455 | #if ENABLE_FEATURE_LESS_REGEXP |
@@ -778,7 +778,7 @@ static void open_file_and_read_lines(void) | |||
778 | } | 778 | } |
779 | readpos = 0; | 779 | readpos = 0; |
780 | readeof = 0; | 780 | readeof = 0; |
781 | linepos = 0; | 781 | last_line_pos = 0; |
782 | terminated = 1; | 782 | terminated = 1; |
783 | read_lines(); | 783 | read_lines(); |
784 | } | 784 | } |