less: more sane way of line numbering. Prepares for
wrap/unwrap and line numbers to be toggleable.
This commit is contained in:
parent
2dfd295726
commit
8f39b72aba
@ -166,6 +166,14 @@ struct globals {
|
||||
USE_FEATURE_LESS_REGEXP(wanted_match = -1;) \
|
||||
} while (0)
|
||||
|
||||
/* flines[] are lines read from stdin, each in malloc'ed buffer.
|
||||
* Line numbers are stored as uint32_t prepended to each line.
|
||||
* Pointer is adjusted so that flines[i] points directly past
|
||||
* line number. Accesor: */
|
||||
#define MEMPTR(p) ((char*)(p) - 4)
|
||||
#define LINENO(p) (*(uint32_t*)((p) - 4))
|
||||
|
||||
|
||||
/* Reset terminal input to normal */
|
||||
static void set_tty_cooked(void)
|
||||
{
|
||||
@ -252,15 +260,13 @@ static void read_lines(void)
|
||||
|
||||
USE_FEATURE_LESS_REGEXP(again0:)
|
||||
|
||||
p = current_line = xmalloc(w);
|
||||
p = current_line = ((char*)xmalloc(w + 4)) + 4;
|
||||
max_fline += last_terminated;
|
||||
if (!last_terminated) {
|
||||
const char *cp = flines[max_fline];
|
||||
if (option_mask32 & FLAG_N)
|
||||
cp += 8;
|
||||
strcpy(current_line, cp);
|
||||
strcpy(p, cp);
|
||||
p += strlen(current_line);
|
||||
free((char*)flines[max_fline]);
|
||||
free(MEMPTR(flines[max_fline]));
|
||||
/* linepos is still valid from previous read_lines() */
|
||||
} else {
|
||||
linepos = 0;
|
||||
@ -324,17 +330,12 @@ static void read_lines(void)
|
||||
reached_eof:
|
||||
last_terminated = terminated;
|
||||
flines = xrealloc_vector(flines, 8, max_fline);
|
||||
if (option_mask32 & FLAG_N) {
|
||||
/* Width of 7 preserves tab spacing in the text */
|
||||
flines[max_fline] = xasprintf(
|
||||
(max_lineno <= 9999999) ? "%7u %s" : "%07u %s",
|
||||
max_lineno % 10000000, current_line);
|
||||
free(current_line);
|
||||
if (terminated)
|
||||
max_lineno++;
|
||||
} else {
|
||||
flines[max_fline] = xrealloc(current_line, strlen(current_line) + 1);
|
||||
}
|
||||
|
||||
flines[max_fline] = (char*)xrealloc(MEMPTR(current_line), strlen(current_line) + 1 + 4) + 4;
|
||||
LINENO(flines[max_fline]) = max_lineno;
|
||||
if (terminated)
|
||||
max_lineno++;
|
||||
|
||||
if (max_fline >= MAXLINES) {
|
||||
eof_error = 0; /* Pretend we saw EOF */
|
||||
break;
|
||||
@ -380,7 +381,7 @@ static void read_lines(void)
|
||||
#endif
|
||||
}
|
||||
max_fline++;
|
||||
current_line = xmalloc(w);
|
||||
current_line = ((char*)xmalloc(w + 4)) + 4;
|
||||
p = current_line;
|
||||
linepos = 0;
|
||||
} /* end of "read lines until we reach cur_fline" loop */
|
||||
@ -487,6 +488,30 @@ static const char ctrlconv[] ALIGN1 =
|
||||
"\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x40\x4b\x4c\x4d\x4e\x4f"
|
||||
"\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f";
|
||||
|
||||
static void lineno_str(char *nbuf9, const char *line)
|
||||
{
|
||||
nbuf9[0] = '\0';
|
||||
if (option_mask32 & FLAG_N) {
|
||||
const char *fmt;
|
||||
unsigned n;
|
||||
|
||||
if (line == empty_line_marker) {
|
||||
memset(nbuf9, ' ', 8);
|
||||
nbuf9[8] = '\0';
|
||||
return;
|
||||
}
|
||||
/* Width of 7 preserves tab spacing in the text */
|
||||
fmt = "%7u ";
|
||||
n = LINENO(line);
|
||||
if (n > 9999999) {
|
||||
n %= 10000000;
|
||||
fmt = "%07u ";
|
||||
}
|
||||
sprintf(nbuf9, fmt, n);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if ENABLE_FEATURE_LESS_REGEXP
|
||||
static void print_found(const char *line)
|
||||
{
|
||||
@ -496,6 +521,7 @@ static void print_found(const char *line)
|
||||
regmatch_t match_structs;
|
||||
|
||||
char buf[width];
|
||||
char nbuf9[9];
|
||||
const char *str = line;
|
||||
char *p = buf;
|
||||
size_t n;
|
||||
@ -532,7 +558,8 @@ static void print_found(const char *line)
|
||||
match_structs.rm_so, str,
|
||||
match_structs.rm_eo - match_structs.rm_so,
|
||||
str + match_structs.rm_so);
|
||||
free(growline); growline = new;
|
||||
free(growline);
|
||||
growline = new;
|
||||
str += match_structs.rm_eo;
|
||||
line += match_structs.rm_eo;
|
||||
eflags = REG_NOTBOL;
|
||||
@ -544,11 +571,12 @@ static void print_found(const char *line)
|
||||
match_status = 1;
|
||||
}
|
||||
|
||||
lineno_str(nbuf9, line);
|
||||
if (!growline) {
|
||||
printf(CLEAR_2_EOL"%s\n", str);
|
||||
printf(CLEAR_2_EOL"%s%s\n", nbuf9, str);
|
||||
return;
|
||||
}
|
||||
printf(CLEAR_2_EOL"%s%s\n", growline, str);
|
||||
printf(CLEAR_2_EOL"%s%s%s\n", nbuf9, growline, str);
|
||||
free(growline);
|
||||
}
|
||||
#else
|
||||
@ -558,10 +586,13 @@ void print_found(const char *line);
|
||||
static void print_ascii(const char *str)
|
||||
{
|
||||
char buf[width];
|
||||
char nbuf9[9];
|
||||
char *p;
|
||||
size_t n;
|
||||
|
||||
printf(CLEAR_2_EOL);
|
||||
lineno_str(nbuf9, str);
|
||||
printf(CLEAR_2_EOL"%s", nbuf9);
|
||||
|
||||
while (*str) {
|
||||
n = strcspn(str, controls);
|
||||
if (n) {
|
||||
@ -670,7 +701,7 @@ static void reinitialize(void)
|
||||
|
||||
if (flines) {
|
||||
for (i = 0; i <= max_fline; i++)
|
||||
free((void*)(flines[i]));
|
||||
free(MEMPTR(flines[i]));
|
||||
free(flines);
|
||||
flines = NULL;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user