aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2008-10-23 22:02:30 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2008-10-23 22:02:30 +0000
commit8f39b72aba3fbb360ea46c6124c9ac90e54372f6 (patch)
treed906a485b128ed12be69f75b096f9f3475b1dba3
parent2dfd295726a0e71c5901214b78cc13a0775a4102 (diff)
downloadbusybox-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.c75
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 */
170static void set_tty_cooked(void) 178static 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
491static 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
491static void print_found(const char *line) 516static 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);
558static void print_ascii(const char *str) 586static 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 }