diff options
| author | Denis Vlasenko <vda.linux@googlemail.com> | 2008-10-23 22:02:30 +0000 |
|---|---|---|
| committer | Denis Vlasenko <vda.linux@googlemail.com> | 2008-10-23 22:02:30 +0000 |
| commit | 8f39b72aba3fbb360ea46c6124c9ac90e54372f6 (patch) | |
| tree | d906a485b128ed12be69f75b096f9f3475b1dba3 | |
| parent | 2dfd295726a0e71c5901214b78cc13a0775a4102 (diff) | |
| download | busybox-w32-8f39b72aba3fbb360ea46c6124c9ac90e54372f6.tar.gz busybox-w32-8f39b72aba3fbb360ea46c6124c9ac90e54372f6.tar.bz2 busybox-w32-8f39b72aba3fbb360ea46c6124c9ac90e54372f6.zip | |
less: more sane way of line numbering. Prepares for
wrap/unwrap and line numbers to be toggleable.
| -rw-r--r-- | miscutils/less.c | 75 |
1 files changed, 53 insertions, 22 deletions
diff --git a/miscutils/less.c b/miscutils/less.c index cd47590ee..049814319 100644 --- a/miscutils/less.c +++ b/miscutils/less.c | |||
| @@ -166,6 +166,14 @@ struct globals { | |||
| 166 | USE_FEATURE_LESS_REGEXP(wanted_match = -1;) \ | 166 | USE_FEATURE_LESS_REGEXP(wanted_match = -1;) \ |
| 167 | } while (0) | 167 | } while (0) |
| 168 | 168 | ||
| 169 | /* flines[] are lines read from stdin, each in malloc'ed buffer. | ||
| 170 | * Line numbers are stored as uint32_t prepended to each line. | ||
| 171 | * Pointer is adjusted so that flines[i] points directly past | ||
| 172 | * line number. Accesor: */ | ||
| 173 | #define MEMPTR(p) ((char*)(p) - 4) | ||
| 174 | #define LINENO(p) (*(uint32_t*)((p) - 4)) | ||
| 175 | |||
| 176 | |||
| 169 | /* Reset terminal input to normal */ | 177 | /* Reset terminal input to normal */ |
| 170 | static void set_tty_cooked(void) | 178 | static void set_tty_cooked(void) |
| 171 | { | 179 | { |
| @@ -252,15 +260,13 @@ static void read_lines(void) | |||
| 252 | 260 | ||
| 253 | USE_FEATURE_LESS_REGEXP(again0:) | 261 | USE_FEATURE_LESS_REGEXP(again0:) |
| 254 | 262 | ||
| 255 | p = current_line = xmalloc(w); | 263 | p = current_line = ((char*)xmalloc(w + 4)) + 4; |
| 256 | max_fline += last_terminated; | 264 | max_fline += last_terminated; |
| 257 | if (!last_terminated) { | 265 | if (!last_terminated) { |
| 258 | const char *cp = flines[max_fline]; | 266 | const char *cp = flines[max_fline]; |
| 259 | if (option_mask32 & FLAG_N) | 267 | strcpy(p, cp); |
| 260 | cp += 8; | ||
| 261 | strcpy(current_line, cp); | ||
| 262 | p += strlen(current_line); | 268 | p += strlen(current_line); |
| 263 | free((char*)flines[max_fline]); | 269 | free(MEMPTR(flines[max_fline])); |
| 264 | /* linepos is still valid from previous read_lines() */ | 270 | /* linepos is still valid from previous read_lines() */ |
| 265 | } else { | 271 | } else { |
| 266 | linepos = 0; | 272 | linepos = 0; |
| @@ -324,17 +330,12 @@ static void read_lines(void) | |||
| 324 | reached_eof: | 330 | reached_eof: |
| 325 | last_terminated = terminated; | 331 | last_terminated = terminated; |
| 326 | flines = xrealloc_vector(flines, 8, max_fline); | 332 | flines = xrealloc_vector(flines, 8, max_fline); |
| 327 | if (option_mask32 & FLAG_N) { | 333 | |
| 328 | /* Width of 7 preserves tab spacing in the text */ | 334 | flines[max_fline] = (char*)xrealloc(MEMPTR(current_line), strlen(current_line) + 1 + 4) + 4; |
| 329 | flines[max_fline] = xasprintf( | 335 | LINENO(flines[max_fline]) = max_lineno; |
| 330 | (max_lineno <= 9999999) ? "%7u %s" : "%07u %s", | 336 | if (terminated) |
| 331 | max_lineno % 10000000, current_line); | 337 | max_lineno++; |
| 332 | free(current_line); | 338 | |
| 333 | if (terminated) | ||
| 334 | max_lineno++; | ||
| 335 | } else { | ||
| 336 | flines[max_fline] = xrealloc(current_line, strlen(current_line) + 1); | ||
| 337 | } | ||
| 338 | if (max_fline >= MAXLINES) { | 339 | if (max_fline >= MAXLINES) { |
| 339 | eof_error = 0; /* Pretend we saw EOF */ | 340 | eof_error = 0; /* Pretend we saw EOF */ |
| 340 | break; | 341 | break; |
| @@ -380,7 +381,7 @@ static void read_lines(void) | |||
| 380 | #endif | 381 | #endif |
| 381 | } | 382 | } |
| 382 | max_fline++; | 383 | max_fline++; |
| 383 | current_line = xmalloc(w); | 384 | current_line = ((char*)xmalloc(w + 4)) + 4; |
| 384 | p = current_line; | 385 | p = current_line; |
| 385 | linepos = 0; | 386 | linepos = 0; |
| 386 | } /* end of "read lines until we reach cur_fline" loop */ | 387 | } /* end of "read lines until we reach cur_fline" loop */ |
| @@ -487,6 +488,30 @@ static const char ctrlconv[] ALIGN1 = | |||
| 487 | "\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x40\x4b\x4c\x4d\x4e\x4f" | 488 | "\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x40\x4b\x4c\x4d\x4e\x4f" |
| 488 | "\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"; | 489 | "\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"; |
| 489 | 490 | ||
| 491 | static void lineno_str(char *nbuf9, const char *line) | ||
| 492 | { | ||
| 493 | nbuf9[0] = '\0'; | ||
| 494 | if (option_mask32 & FLAG_N) { | ||
| 495 | const char *fmt; | ||
| 496 | unsigned n; | ||
| 497 | |||
| 498 | if (line == empty_line_marker) { | ||
| 499 | memset(nbuf9, ' ', 8); | ||
| 500 | nbuf9[8] = '\0'; | ||
| 501 | return; | ||
| 502 | } | ||
| 503 | /* Width of 7 preserves tab spacing in the text */ | ||
| 504 | fmt = "%7u "; | ||
| 505 | n = LINENO(line); | ||
| 506 | if (n > 9999999) { | ||
| 507 | n %= 10000000; | ||
| 508 | fmt = "%07u "; | ||
| 509 | } | ||
| 510 | sprintf(nbuf9, fmt, n); | ||
| 511 | } | ||
| 512 | } | ||
| 513 | |||
| 514 | |||
| 490 | #if ENABLE_FEATURE_LESS_REGEXP | 515 | #if ENABLE_FEATURE_LESS_REGEXP |
| 491 | static void print_found(const char *line) | 516 | static void print_found(const char *line) |
| 492 | { | 517 | { |
| @@ -496,6 +521,7 @@ static void print_found(const char *line) | |||
| 496 | regmatch_t match_structs; | 521 | regmatch_t match_structs; |
| 497 | 522 | ||
| 498 | char buf[width]; | 523 | char buf[width]; |
| 524 | char nbuf9[9]; | ||
| 499 | const char *str = line; | 525 | const char *str = line; |
| 500 | char *p = buf; | 526 | char *p = buf; |
| 501 | size_t n; | 527 | size_t n; |
| @@ -532,7 +558,8 @@ static void print_found(const char *line) | |||
| 532 | match_structs.rm_so, str, | 558 | match_structs.rm_so, str, |
| 533 | match_structs.rm_eo - match_structs.rm_so, | 559 | match_structs.rm_eo - match_structs.rm_so, |
| 534 | str + match_structs.rm_so); | 560 | str + match_structs.rm_so); |
| 535 | free(growline); growline = new; | 561 | free(growline); |
| 562 | growline = new; | ||
| 536 | str += match_structs.rm_eo; | 563 | str += match_structs.rm_eo; |
| 537 | line += match_structs.rm_eo; | 564 | line += match_structs.rm_eo; |
| 538 | eflags = REG_NOTBOL; | 565 | eflags = REG_NOTBOL; |
| @@ -544,11 +571,12 @@ static void print_found(const char *line) | |||
| 544 | match_status = 1; | 571 | match_status = 1; |
| 545 | } | 572 | } |
| 546 | 573 | ||
| 574 | lineno_str(nbuf9, line); | ||
| 547 | if (!growline) { | 575 | if (!growline) { |
| 548 | printf(CLEAR_2_EOL"%s\n", str); | 576 | printf(CLEAR_2_EOL"%s%s\n", nbuf9, str); |
| 549 | return; | 577 | return; |
| 550 | } | 578 | } |
| 551 | printf(CLEAR_2_EOL"%s%s\n", growline, str); | 579 | printf(CLEAR_2_EOL"%s%s%s\n", nbuf9, growline, str); |
| 552 | free(growline); | 580 | free(growline); |
| 553 | } | 581 | } |
| 554 | #else | 582 | #else |
| @@ -558,10 +586,13 @@ void print_found(const char *line); | |||
| 558 | static void print_ascii(const char *str) | 586 | static void print_ascii(const char *str) |
| 559 | { | 587 | { |
| 560 | char buf[width]; | 588 | char buf[width]; |
| 589 | char nbuf9[9]; | ||
| 561 | char *p; | 590 | char *p; |
| 562 | size_t n; | 591 | size_t n; |
| 563 | 592 | ||
| 564 | printf(CLEAR_2_EOL); | 593 | lineno_str(nbuf9, str); |
| 594 | printf(CLEAR_2_EOL"%s", nbuf9); | ||
| 595 | |||
| 565 | while (*str) { | 596 | while (*str) { |
| 566 | n = strcspn(str, controls); | 597 | n = strcspn(str, controls); |
| 567 | if (n) { | 598 | if (n) { |
| @@ -670,7 +701,7 @@ static void reinitialize(void) | |||
| 670 | 701 | ||
| 671 | if (flines) { | 702 | if (flines) { |
| 672 | for (i = 0; i <= max_fline; i++) | 703 | for (i = 0; i <= max_fline; i++) |
| 673 | free((void*)(flines[i])); | 704 | free(MEMPTR(flines[i])); |
| 674 | free(flines); | 705 | free(flines); |
| 675 | flines = NULL; | 706 | flines = NULL; |
| 676 | } | 707 | } |
