quick patchs: drop founded memory leak, more libbb, more C-compatibility, size reduction
This commit is contained in:
parent
4cbe45934e
commit
a0ae6de848
173
miscutils/less.c
173
miscutils/less.c
@ -20,26 +20,26 @@
|
|||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||||
* 02111-1307 USA
|
* 02111-1307 USA
|
||||||
*
|
*
|
||||||
* This program needs a lot of development, so consider it in a beta stage
|
* This program needs a lot of development, so consider it in a beta stage
|
||||||
* at best.
|
* at best.
|
||||||
*
|
*
|
||||||
* TODO:
|
* TODO:
|
||||||
* - Add more regular expression support - search modifiers, certain matches, etc.
|
* - Add more regular expression support - search modifiers, certain matches, etc.
|
||||||
* - Add more complex bracket searching - currently, nested brackets are
|
* - Add more complex bracket searching - currently, nested brackets are
|
||||||
* not considered.
|
* not considered.
|
||||||
* - Add support for "F" as an input. This causes less to act in
|
* - Add support for "F" as an input. This causes less to act in
|
||||||
* a similar way to tail -f.
|
* a similar way to tail -f.
|
||||||
* - Check for binary files, and prompt the user if a binary file
|
* - Check for binary files, and prompt the user if a binary file
|
||||||
* is detected.
|
* is detected.
|
||||||
* - Allow horizontal scrolling. Currently, lines simply continue onto
|
* - Allow horizontal scrolling. Currently, lines simply continue onto
|
||||||
* the next line, per the terminal's discretion
|
* the next line, per the terminal's discretion
|
||||||
*
|
*
|
||||||
* Notes:
|
* Notes:
|
||||||
* - filename is an array and not a pointer because that avoids all sorts
|
* - filename is an array and not a pointer because that avoids all sorts
|
||||||
* of complications involving the fact that something that is pointed to
|
* of complications involving the fact that something that is pointed to
|
||||||
* will be changed if the pointer is changed.
|
* will be changed if the pointer is changed.
|
||||||
* - the inp file pointer is used so that keyboard input works after
|
* - the inp file pointer is used so that keyboard input works after
|
||||||
* redirected input has been read from stdin
|
* redirected input has been read from stdin
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -77,7 +77,7 @@
|
|||||||
#define NORMAL "\033[0m"
|
#define NORMAL "\033[0m"
|
||||||
|
|
||||||
/* The escape code to clear the screen */
|
/* The escape code to clear the screen */
|
||||||
#define CLEAR "\033[2J"
|
#define CLEAR "\033[H\033[J"
|
||||||
|
|
||||||
/* Maximum number of lines in a file */
|
/* Maximum number of lines in a file */
|
||||||
#define MAXLINES 10000
|
#define MAXLINES 10000
|
||||||
@ -142,13 +142,6 @@ static void set_tty_cooked(void) {
|
|||||||
|
|
||||||
/* Set terminal input to raw mode (taken from vi.c) */
|
/* Set terminal input to raw mode (taken from vi.c) */
|
||||||
static void set_tty_raw(void) {
|
static void set_tty_raw(void) {
|
||||||
tcgetattr(0, &term_orig);
|
|
||||||
term_vi = term_orig;
|
|
||||||
term_vi.c_lflag &= (~ICANON & ~ECHO);
|
|
||||||
term_vi.c_iflag &= (~IXON & ~ICRNL);
|
|
||||||
term_vi.c_oflag &= (~ONLCR);
|
|
||||||
term_vi.c_cc[VMIN] = 1;
|
|
||||||
term_vi.c_cc[VTIME] = 0;
|
|
||||||
tcsetattr(0, TCSANOW, &term_vi);
|
tcsetattr(0, TCSANOW, &term_vi);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -169,36 +162,34 @@ static void tless_exit(int code) {
|
|||||||
special return codes. Note that this function works best with raw input. */
|
special return codes. Note that this function works best with raw input. */
|
||||||
static int tless_getch(void) {
|
static int tless_getch(void) {
|
||||||
|
|
||||||
set_tty_raw();
|
int input;
|
||||||
char input_key[3];
|
|
||||||
|
|
||||||
input_key[0] = getc(inp);
|
set_tty_raw();
|
||||||
|
|
||||||
|
input = getc(inp);
|
||||||
/* Detect escape sequences (i.e. arrow keys) and handle
|
/* Detect escape sequences (i.e. arrow keys) and handle
|
||||||
them accordingly */
|
them accordingly */
|
||||||
|
|
||||||
if (input_key[0] == '\033') {
|
if (input == '\033' && getc(inp) == '[') {
|
||||||
input_key[1] = getc(inp);
|
input = getc(inp);
|
||||||
input_key[2] = getc(inp);
|
|
||||||
set_tty_cooked();
|
set_tty_cooked();
|
||||||
if (input_key[1] == '[') {
|
if (input == REAL_KEY_UP)
|
||||||
if (input_key[2] == REAL_KEY_UP)
|
return KEY_UP;
|
||||||
return KEY_UP;
|
else if (input == REAL_KEY_DOWN)
|
||||||
else if (input_key[2] == REAL_KEY_DOWN)
|
return KEY_DOWN;
|
||||||
return KEY_DOWN;
|
else if (input == REAL_KEY_RIGHT)
|
||||||
else if (input_key[2] == REAL_KEY_RIGHT)
|
return KEY_RIGHT;
|
||||||
return KEY_RIGHT;
|
else if (input == REAL_KEY_LEFT)
|
||||||
else if (input_key[2] == REAL_KEY_LEFT)
|
return KEY_LEFT;
|
||||||
return KEY_LEFT;
|
else if (input == REAL_PAGE_UP)
|
||||||
else if (input_key[2] == REAL_PAGE_UP)
|
return PAGE_UP;
|
||||||
return PAGE_UP;
|
else if (input == REAL_PAGE_DOWN)
|
||||||
else if (input_key[2] == REAL_PAGE_DOWN)
|
return PAGE_DOWN;
|
||||||
return PAGE_DOWN;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/* The input is a normal ASCII value */
|
/* The input is a normal ASCII value */
|
||||||
else {
|
else {
|
||||||
set_tty_cooked();
|
set_tty_cooked();
|
||||||
return input_key[0];
|
return input;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -222,8 +213,7 @@ static void add_linenumbers(void) {
|
|||||||
|
|
||||||
for (i = 0; i <= num_flines; i++) {
|
for (i = 0; i <= num_flines; i++) {
|
||||||
safe_strncpy(current_line, flines[i], 256);
|
safe_strncpy(current_line, flines[i], 256);
|
||||||
flines[i] = xrealloc(flines[i], strlen(current_line) + 7);
|
bb_xasprintf(&flines[i],"%5d %s", i + 1, current_line);
|
||||||
sprintf(flines[i],"%5d %s", i + 1, current_line);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -241,12 +231,12 @@ static void data_readlines(void) {
|
|||||||
rewind(fp);
|
rewind(fp);
|
||||||
/* Initialise fp */
|
/* Initialise fp */
|
||||||
flines = malloc(i * sizeof(char *));
|
flines = malloc(i * sizeof(char *));
|
||||||
|
|
||||||
for (i = 0; (!feof(fp)) && (i <= MAXLINES); i++) {
|
for (i = 0; (!feof(fp)) && (i <= MAXLINES); i++) {
|
||||||
strcpy(current_line, "");
|
strcpy(current_line, "");
|
||||||
fgets(current_line, 256, fp);
|
fgets(current_line, 256, fp);
|
||||||
bb_xferror(fp, filename);
|
bb_xferror(fp, filename);
|
||||||
flines[i] = (char *) bb_xstrndup(current_line, (strlen(current_line) + 1) * sizeof(char));
|
flines[i] = bb_xstrdup(current_line);
|
||||||
}
|
}
|
||||||
num_flines = i - 2;
|
num_flines = i - 2;
|
||||||
|
|
||||||
@ -258,7 +248,7 @@ static void data_readlines(void) {
|
|||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
|
||||||
inp = (inp_stdin) ? fopen(CURRENT_TTY, "r") : stdin;
|
inp = (inp_stdin) ? fopen(CURRENT_TTY, "r") : stdin;
|
||||||
|
|
||||||
if (ea_inp_stdin) {
|
if (ea_inp_stdin) {
|
||||||
fclose(inp);
|
fclose(inp);
|
||||||
inp = fopen(CURRENT_TTY, "r");
|
inp = fopen(CURRENT_TTY, "r");
|
||||||
@ -307,7 +297,7 @@ static void m_status_print(void) {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
percentage = calc_percent();
|
percentage = calc_percent();
|
||||||
printf("%i%s %s", percentage, "%", NORMAL);
|
printf("%i%% %s", percentage, NORMAL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -325,11 +315,11 @@ static void medium_status_print(void) {
|
|||||||
percentage = calc_percent();
|
percentage = calc_percent();
|
||||||
|
|
||||||
if (!line_pos)
|
if (!line_pos)
|
||||||
printf("%s%s %i%s%s", HIGHLIGHT, filename, percentage, "%", NORMAL);
|
printf("%s%s %i%%%s", HIGHLIGHT, filename, percentage, NORMAL);
|
||||||
else if (line_pos == num_flines - height + 2)
|
else if (line_pos == num_flines - height + 2)
|
||||||
printf("%s(END)%s", HIGHLIGHT, NORMAL);
|
printf("%s(END)%s", HIGHLIGHT, NORMAL);
|
||||||
else
|
else
|
||||||
printf("%s%i%s%s", HIGHLIGHT, percentage, "%", NORMAL);
|
printf("%s%i%%%s", HIGHLIGHT, percentage, NORMAL);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -368,15 +358,12 @@ static void buffer_print(void) {
|
|||||||
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
printf("%s", CLEAR);
|
||||||
if (num_flines >= height - 2) {
|
if (num_flines >= height - 2) {
|
||||||
printf("%s", CLEAR);
|
|
||||||
move_cursor(0,0);
|
|
||||||
for (i = 0; i < height - 1; i++)
|
for (i = 0; i < height - 1; i++)
|
||||||
printf("%s", buffer[i]);
|
printf("%s", buffer[i]);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
printf("%s", CLEAR);
|
|
||||||
move_cursor(0,0);
|
|
||||||
for (i = 1; i < (height - 1 - num_flines); i++)
|
for (i = 1; i < (height - 1 - num_flines); i++)
|
||||||
putchar('\n');
|
putchar('\n');
|
||||||
for (i = 0; i < height - 1; i++)
|
for (i = 0; i < height - 1; i++)
|
||||||
@ -391,9 +378,14 @@ static void buffer_init(void) {
|
|||||||
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* malloc the number of lines needed for the buffer */
|
if(buffer == NULL) {
|
||||||
buffer = xrealloc(buffer, height * sizeof(char *));
|
/* malloc the number of lines needed for the buffer */
|
||||||
|
buffer = xrealloc(buffer, height * sizeof(char *));
|
||||||
|
} else {
|
||||||
|
for (i = 0; i < (height - 1); i++)
|
||||||
|
free(buffer[i]);
|
||||||
|
}
|
||||||
|
|
||||||
/* Fill the buffer until the end of the file or the
|
/* Fill the buffer until the end of the file or the
|
||||||
end of the buffer is reached */
|
end of the buffer is reached */
|
||||||
for (i = 0; (i < (height - 1)) && (i <= num_flines); i++) {
|
for (i = 0; (i < (height - 1)) && (i <= num_flines); i++) {
|
||||||
@ -402,7 +394,7 @@ static void buffer_init(void) {
|
|||||||
|
|
||||||
/* If the buffer still isn't full, fill it with blank lines */
|
/* If the buffer still isn't full, fill it with blank lines */
|
||||||
for (; i < (height - 1); i++) {
|
for (; i < (height - 1); i++) {
|
||||||
buffer[i] = "";
|
buffer[i] = bb_xstrdup("");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -414,16 +406,20 @@ static void buffer_down(int nlines) {
|
|||||||
if (!past_eof) {
|
if (!past_eof) {
|
||||||
if (line_pos + (height - 3) + nlines < num_flines) {
|
if (line_pos + (height - 3) + nlines < num_flines) {
|
||||||
line_pos += nlines;
|
line_pos += nlines;
|
||||||
for (i = 0; i < (height - 1); i++)
|
for (i = 0; i < (height - 1); i++) {
|
||||||
|
free(buffer[i]);
|
||||||
buffer[i] = (char *) bb_xstrdup(flines[line_pos + i]);
|
buffer[i] = (char *) bb_xstrdup(flines[line_pos + i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* As the number of lines requested was too large, we just move
|
/* As the number of lines requested was too large, we just move
|
||||||
to the end of the file */
|
to the end of the file */
|
||||||
while (line_pos + (height - 3) + 1 < num_flines) {
|
while (line_pos + (height - 3) + 1 < num_flines) {
|
||||||
line_pos += 1;
|
line_pos += 1;
|
||||||
for (i = 0; i < (height - 1); i++)
|
for (i = 0; i < (height - 1); i++) {
|
||||||
|
free(buffer[i]);
|
||||||
buffer[i] = (char *) bb_xstrdup(flines[line_pos + i]);
|
buffer[i] = (char *) bb_xstrdup(flines[line_pos + i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -441,16 +437,20 @@ static void buffer_up(int nlines) {
|
|||||||
if (!past_eof) {
|
if (!past_eof) {
|
||||||
if (line_pos - nlines >= 0) {
|
if (line_pos - nlines >= 0) {
|
||||||
line_pos -= nlines;
|
line_pos -= nlines;
|
||||||
for (i = 0; i < (height - 1); i++)
|
for (i = 0; i < (height - 1); i++) {
|
||||||
|
free(buffer[i]);
|
||||||
buffer[i] = (char *) bb_xstrdup(flines[line_pos + i]);
|
buffer[i] = (char *) bb_xstrdup(flines[line_pos + i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* As the requested number of lines to move was too large, we
|
/* As the requested number of lines to move was too large, we
|
||||||
move one line up at a time until we can't. */
|
move one line up at a time until we can't. */
|
||||||
while (line_pos != 0) {
|
while (line_pos != 0) {
|
||||||
line_pos -= 1;
|
line_pos -= 1;
|
||||||
for (i = 0; i < (height - 1); i++)
|
for (i = 0; i < (height - 1); i++) {
|
||||||
|
free(buffer[i]);
|
||||||
buffer[i] = (char *) bb_xstrdup(flines[line_pos + i]);
|
buffer[i] = (char *) bb_xstrdup(flines[line_pos + i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -469,11 +469,12 @@ static void buffer_up(int nlines) {
|
|||||||
/* We only move part of the buffer, as the rest
|
/* We only move part of the buffer, as the rest
|
||||||
is past the EOF */
|
is past the EOF */
|
||||||
for (i = 0; i < (height - 1); i++) {
|
for (i = 0; i < (height - 1); i++) {
|
||||||
|
free(buffer[i]);
|
||||||
if (i < tilde_line - nlines + 1)
|
if (i < tilde_line - nlines + 1)
|
||||||
buffer[i] = (char *) bb_xstrdup(flines[line_pos + i]);
|
buffer[i] = (char *) bb_xstrdup(flines[line_pos + i]);
|
||||||
else {
|
else {
|
||||||
if (line_pos >= num_flines - height + 2)
|
if (line_pos >= num_flines - height + 2)
|
||||||
buffer[i] = "~\n";
|
buffer[i] = bb_xstrdup("~\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -491,12 +492,15 @@ static void buffer_line(int linenum) {
|
|||||||
printf("%s%s%i%s", HIGHLIGHT, "Cannot seek to line number ", linenum, NORMAL);
|
printf("%s%s%i%s", HIGHLIGHT, "Cannot seek to line number ", linenum, NORMAL);
|
||||||
}
|
}
|
||||||
else if (linenum < (num_flines - height - 2)) {
|
else if (linenum < (num_flines - height - 2)) {
|
||||||
for (i = 0; i < (height - 1); i++)
|
for (i = 0; i < (height - 1); i++) {
|
||||||
|
free(buffer[i]);
|
||||||
buffer[i] = (char *) bb_xstrdup(flines[linenum + i]);
|
buffer[i] = (char *) bb_xstrdup(flines[linenum + i]);
|
||||||
|
}
|
||||||
line_pos = linenum;
|
line_pos = linenum;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
for (i = 0; i < (height - 1); i++) {
|
for (i = 0; i < (height - 1); i++) {
|
||||||
|
free(buffer[i]);
|
||||||
if (linenum + i < num_flines + 2)
|
if (linenum + i < num_flines + 2)
|
||||||
buffer[i] = (char *) bb_xstrdup(flines[linenum + i]);
|
buffer[i] = (char *) bb_xstrdup(flines[linenum + i]);
|
||||||
else
|
else
|
||||||
@ -516,7 +520,7 @@ static void reinitialise(void) {
|
|||||||
for (i = 0; i <= num_flines; i++)
|
for (i = 0; i <= num_flines; i++)
|
||||||
free(flines[i]);
|
free(flines[i]);
|
||||||
free(flines);
|
free(flines);
|
||||||
|
|
||||||
data_readlines();
|
data_readlines();
|
||||||
buffer_init();
|
buffer_init();
|
||||||
buffer_print();
|
buffer_print();
|
||||||
@ -629,15 +633,10 @@ static void colon_process(void) {
|
|||||||
|
|
||||||
static char *insert_highlights (char *line, int start, int end) {
|
static char *insert_highlights (char *line, int start, int end) {
|
||||||
|
|
||||||
char *new_line = (char *) malloc((sizeof(char) * (strlen(line) + 1)) + 10);
|
char *new_line;
|
||||||
|
|
||||||
memset(new_line, 0, ((sizeof(char) * (strlen(line) + 1)) + 10));
|
|
||||||
strncat(new_line, line, start);
|
|
||||||
strcat(new_line, HIGHLIGHT);
|
|
||||||
strncat(new_line, line + start, end - start);
|
|
||||||
strcat(new_line, NORMAL);
|
|
||||||
strncat(new_line, line + end, strlen(line) - end);
|
|
||||||
|
|
||||||
|
bb_xasprintf(&new_line, "%.*s%s%.*s%s%s", start, line, HIGHLIGHT,
|
||||||
|
end - start, line + start, NORMAL, line + end);
|
||||||
return new_line;
|
return new_line;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -652,7 +651,7 @@ static char *process_regex_on_line(char *line, regex_t *pattern) {
|
|||||||
char sub_line[256];
|
char sub_line[256];
|
||||||
int prev_eo = 0;
|
int prev_eo = 0;
|
||||||
regmatch_t match_structs;
|
regmatch_t match_structs;
|
||||||
|
|
||||||
memset(sub_line, 0, 256);
|
memset(sub_line, 0, 256);
|
||||||
strcpy(line2, line);
|
strcpy(line2, line);
|
||||||
|
|
||||||
@ -869,7 +868,7 @@ static void show_flag_status(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
clear_line();
|
clear_line();
|
||||||
printf("%s%s%i%s", HIGHLIGHT, "The status of the flag is: ", flag_val, NORMAL);
|
printf("%s%s%i%s", HIGHLIGHT, "The status of the flag is: ", flag_val != 0, NORMAL);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -940,7 +939,7 @@ static void goto_mark(void) {
|
|||||||
printf("Go to mark: ");
|
printf("Go to mark: ");
|
||||||
letter = tless_getch();
|
letter = tless_getch();
|
||||||
clear_line();
|
clear_line();
|
||||||
|
|
||||||
if (isalpha(letter)) {
|
if (isalpha(letter)) {
|
||||||
for (i = 0; i <= num_marks; i++)
|
for (i = 0; i <= num_marks; i++)
|
||||||
if (letter == mark_lines[i][0]) {
|
if (letter == mark_lines[i][0]) {
|
||||||
@ -985,7 +984,7 @@ static void match_right_bracket(char bracket) {
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
clear_line();
|
clear_line();
|
||||||
|
|
||||||
if (strchr(flines[line_pos], bracket) == NULL)
|
if (strchr(flines[line_pos], bracket) == NULL)
|
||||||
printf("%s%s%s", HIGHLIGHT, "No bracket in top line", NORMAL);
|
printf("%s%s%s", HIGHLIGHT, "No bracket in top line", NORMAL);
|
||||||
else {
|
else {
|
||||||
@ -1010,7 +1009,7 @@ static void match_left_bracket (char bracket) {
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
clear_line();
|
clear_line();
|
||||||
|
|
||||||
if (strchr(flines[line_pos + height - 2], bracket) == NULL) {
|
if (strchr(flines[line_pos + height - 2], bracket) == NULL) {
|
||||||
printf("%s%s%s", HIGHLIGHT, "No bracket in bottom line", NORMAL);
|
printf("%s%s%s", HIGHLIGHT, "No bracket in bottom line", NORMAL);
|
||||||
printf("%s", flines[line_pos + height]);
|
printf("%s", flines[line_pos + height]);
|
||||||
@ -1168,6 +1167,14 @@ int less_main(int argc, char **argv) {
|
|||||||
|
|
||||||
strcpy(filename, (inp_stdin) ? "stdin" : files[0]);
|
strcpy(filename, (inp_stdin) ? "stdin" : files[0]);
|
||||||
tty_width_height();
|
tty_width_height();
|
||||||
|
tcgetattr(0, &term_orig);
|
||||||
|
term_vi = term_orig;
|
||||||
|
term_vi.c_lflag &= (~ICANON & ~ECHO);
|
||||||
|
term_vi.c_iflag &= (~IXON & ~ICRNL);
|
||||||
|
term_vi.c_oflag &= (~ONLCR);
|
||||||
|
term_vi.c_cc[VMIN] = 1;
|
||||||
|
term_vi.c_cc[VTIME] = 0;
|
||||||
|
|
||||||
data_readlines();
|
data_readlines();
|
||||||
buffer_init();
|
buffer_init();
|
||||||
buffer_print();
|
buffer_print();
|
||||||
|
Loading…
Reference in New Issue
Block a user