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 | |
| 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')
| -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 | } |
