mirror of https://github.com/mirror/busybox.git
This is synced from dash-0.4.17 and full ready for insert to new busybox
version: ftp://ftp.simtreas.ru/pub/my/bb/new News: - code is smalest! - support ${var...} expr - used new very strongly steal controlling terminal1_00_stable_10817
parent
9b47661165
commit
c470f4477a
14595
shell/ash.c
14595
shell/ash.c
File diff suppressed because it is too large
Load Diff
189
shell/cmdedit.c
189
shell/cmdedit.c
|
@ -9,7 +9,7 @@
|
||||||
* Adam Rogoyski <rogoyski@cs.utexas.edu>
|
* Adam Rogoyski <rogoyski@cs.utexas.edu>
|
||||||
* Dave Cinege <dcinege@psychosis.com>
|
* Dave Cinege <dcinege@psychosis.com>
|
||||||
* Jakub Jelinek (c) 1995
|
* Jakub Jelinek (c) 1995
|
||||||
* Erik Andersen <andersen@codepoet.org> (Majorly adjusted for busybox)
|
* Erik Andersen <andersee@debian.org> (Majorly adjusted for busybox)
|
||||||
*
|
*
|
||||||
* This code is 'as is' with no warranty.
|
* This code is 'as is' with no warranty.
|
||||||
*
|
*
|
||||||
|
@ -63,7 +63,7 @@
|
||||||
|
|
||||||
#define D(x) x
|
#define D(x) x
|
||||||
|
|
||||||
#endif /* TEST */
|
#endif /* TEST */
|
||||||
|
|
||||||
#ifdef CONFIG_FEATURE_COMMAND_TAB_COMPLETION
|
#ifdef CONFIG_FEATURE_COMMAND_TAB_COMPLETION
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
|
@ -86,7 +86,7 @@
|
||||||
# else
|
# else
|
||||||
# include <pwd.h>
|
# include <pwd.h>
|
||||||
# endif /* TEST */
|
# endif /* TEST */
|
||||||
#endif /* advanced FEATURES */
|
#endif /* advanced FEATURES */
|
||||||
|
|
||||||
|
|
||||||
/* Maximum length of the linked list for the command line history */
|
/* Maximum length of the linked list for the command line history */
|
||||||
|
@ -115,30 +115,30 @@ static struct termios initial_settings, new_settings;
|
||||||
|
|
||||||
|
|
||||||
static
|
static
|
||||||
volatile int cmdedit_termw = 80; /* actual terminal width */
|
volatile int cmdedit_termw = 80; /* actual terminal width */
|
||||||
static
|
static
|
||||||
volatile int handlers_sets = 0; /* Set next bites: */
|
volatile int handlers_sets = 0; /* Set next bites: */
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
SET_ATEXIT = 1, /* when atexit() has been called
|
SET_ATEXIT = 1, /* when atexit() has been called
|
||||||
and get euid,uid,gid to fast compare */
|
and get euid,uid,gid to fast compare */
|
||||||
SET_WCHG_HANDLERS = 2, /* winchg signal handler */
|
SET_WCHG_HANDLERS = 2, /* winchg signal handler */
|
||||||
SET_RESET_TERM = 4, /* if the terminal needs to be reset upon exit */
|
SET_RESET_TERM = 4, /* if the terminal needs to be reset upon exit */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static int cmdedit_x; /* real x terminal position */
|
static int cmdedit_x; /* real x terminal position */
|
||||||
static int cmdedit_y; /* pseudoreal y terminal position */
|
static int cmdedit_y; /* pseudoreal y terminal position */
|
||||||
static int cmdedit_prmt_len; /* lenght prompt without colores string */
|
static int cmdedit_prmt_len; /* lenght prompt without colores string */
|
||||||
|
|
||||||
static int cursor; /* required global for signal handler */
|
static int cursor; /* required global for signal handler */
|
||||||
static int len; /* --- "" - - "" - -"- --""-- --""--- */
|
static int len; /* --- "" - - "" - -"- --""-- --""--- */
|
||||||
static char *command_ps; /* --- "" - - "" - -"- --""-- --""--- */
|
static char *command_ps; /* --- "" - - "" - -"- --""-- --""--- */
|
||||||
static
|
static
|
||||||
#ifndef CONFIG_FEATURE_SH_FANCY_PROMPT
|
#ifndef CONFIG_FEATURE_SH_FANCY_PROMPT
|
||||||
const
|
const
|
||||||
#endif
|
#endif
|
||||||
char *cmdedit_prompt; /* --- "" - - "" - -"- --""-- --""--- */
|
char *cmdedit_prompt; /* --- "" - - "" - -"- --""-- --""--- */
|
||||||
|
|
||||||
#ifdef CONFIG_FEATURE_GETUSERNAME_AND_HOMEDIR
|
#ifdef CONFIG_FEATURE_GETUSERNAME_AND_HOMEDIR
|
||||||
static char *user_buf = "";
|
static char *user_buf = "";
|
||||||
|
@ -161,14 +161,19 @@ static int my_euid;
|
||||||
static int my_uid;
|
static int my_uid;
|
||||||
static int my_gid;
|
static int my_gid;
|
||||||
|
|
||||||
#endif /* CONFIG_FEATURE_COMMAND_TAB_COMPLETION */
|
#endif /* CONFIG_FEATURE_COMMAND_TAB_COMPLETION */
|
||||||
|
|
||||||
|
/* It seems that libc5 doesn't know what a sighandler_t is... */
|
||||||
|
#if (__GLIBC__ <= 2) && (__GLIBC_MINOR__ < 1)
|
||||||
|
typedef void (*sighandler_t) (int);
|
||||||
|
#endif
|
||||||
|
|
||||||
static void cmdedit_setwidth(int w, int redraw_flg);
|
static void cmdedit_setwidth(int w, int redraw_flg);
|
||||||
|
|
||||||
static void win_changed(int nsig)
|
static void win_changed(int nsig)
|
||||||
{
|
{
|
||||||
struct winsize win = { 0, 0, 0, 0 };
|
struct winsize win = { 0, 0, 0, 0 };
|
||||||
static sighandler_t previous_SIGWINCH_handler; /* for reset */
|
static sighandler_t previous_SIGWINCH_handler; /* for reset */
|
||||||
|
|
||||||
/* emulate || signal call */
|
/* emulate || signal call */
|
||||||
if (nsig == -SIGWINCH || nsig == SIGWINCH) {
|
if (nsig == -SIGWINCH || nsig == SIGWINCH) {
|
||||||
|
@ -179,13 +184,13 @@ static void win_changed(int nsig)
|
||||||
}
|
}
|
||||||
/* Unix not all standart in recall signal */
|
/* Unix not all standart in recall signal */
|
||||||
|
|
||||||
if (nsig == -SIGWINCH) /* save previous handler */
|
if (nsig == -SIGWINCH) /* save previous handler */
|
||||||
previous_SIGWINCH_handler = signal(SIGWINCH, win_changed);
|
previous_SIGWINCH_handler = signal(SIGWINCH, win_changed);
|
||||||
else if (nsig == SIGWINCH) /* signaled called handler */
|
else if (nsig == SIGWINCH) /* signaled called handler */
|
||||||
signal(SIGWINCH, win_changed); /* set for next call */
|
signal(SIGWINCH, win_changed); /* set for next call */
|
||||||
else /* nsig == 0 */
|
else /* nsig == 0 */
|
||||||
/* set previous handler */
|
/* set previous handler */
|
||||||
signal(SIGWINCH, previous_SIGWINCH_handler); /* reset */
|
signal(SIGWINCH, previous_SIGWINCH_handler); /* reset */
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cmdedit_reset_term(void)
|
static void cmdedit_reset_term(void)
|
||||||
|
@ -211,9 +216,9 @@ static void cmdedit_set_out_char(int next_char)
|
||||||
int c = (int)((unsigned char) command_ps[cursor]);
|
int c = (int)((unsigned char) command_ps[cursor]);
|
||||||
|
|
||||||
if (c == 0)
|
if (c == 0)
|
||||||
c = ' '; /* destroy end char? */
|
c = ' '; /* destroy end char? */
|
||||||
#ifdef CONFIG_FEATURE_NONPRINTABLE_INVERSE_PUT
|
#ifdef CONFIG_FEATURE_NONPRINTABLE_INVERSE_PUT
|
||||||
if (!Isprint(c)) { /* Inverse put non-printable characters */
|
if (!Isprint(c)) { /* Inverse put non-printable characters */
|
||||||
if (c >= 128)
|
if (c >= 128)
|
||||||
c -= 128;
|
c -= 128;
|
||||||
if (c < ' ')
|
if (c < ' ')
|
||||||
|
@ -270,9 +275,9 @@ static void input_backward(int num)
|
||||||
{
|
{
|
||||||
if (num > cursor)
|
if (num > cursor)
|
||||||
num = cursor;
|
num = cursor;
|
||||||
cursor -= num; /* new cursor (in command, not terminal) */
|
cursor -= num; /* new cursor (in command, not terminal) */
|
||||||
|
|
||||||
if (cmdedit_x >= num) { /* no to up line */
|
if (cmdedit_x >= num) { /* no to up line */
|
||||||
cmdedit_x -= num;
|
cmdedit_x -= num;
|
||||||
if (num < 4)
|
if (num < 4)
|
||||||
while (num-- > 0)
|
while (num-- > 0)
|
||||||
|
@ -284,22 +289,22 @@ static void input_backward(int num)
|
||||||
int count_y;
|
int count_y;
|
||||||
|
|
||||||
if (cmdedit_x) {
|
if (cmdedit_x) {
|
||||||
putchar('\r'); /* back to first terminal pos. */
|
putchar('\r'); /* back to first terminal pos. */
|
||||||
num -= cmdedit_x; /* set previous backward */
|
num -= cmdedit_x; /* set previous backward */
|
||||||
}
|
}
|
||||||
count_y = 1 + num / cmdedit_termw;
|
count_y = 1 + num / cmdedit_termw;
|
||||||
printf("\033[%dA", count_y);
|
printf("\033[%dA", count_y);
|
||||||
cmdedit_y -= count_y;
|
cmdedit_y -= count_y;
|
||||||
/* require forward after uping */
|
/* require forward after uping */
|
||||||
cmdedit_x = cmdedit_termw * count_y - num;
|
cmdedit_x = cmdedit_termw * count_y - num;
|
||||||
printf("\033[%dC", cmdedit_x); /* set term cursor */
|
printf("\033[%dC", cmdedit_x); /* set term cursor */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void put_prompt(void)
|
static void put_prompt(void)
|
||||||
{
|
{
|
||||||
out1str(cmdedit_prompt);
|
out1str(cmdedit_prompt);
|
||||||
cmdedit_x = cmdedit_prmt_len; /* count real x terminal position */
|
cmdedit_x = cmdedit_prmt_len; /* count real x terminal position */
|
||||||
cursor = 0;
|
cursor = 0;
|
||||||
cmdedit_y = 0; /* new quasireal y */
|
cmdedit_y = 0; /* new quasireal y */
|
||||||
}
|
}
|
||||||
|
@ -437,12 +442,12 @@ static void parse_prompt(const char *prmt_ptr)
|
||||||
/* draw promt, editor line, and clear tail */
|
/* draw promt, editor line, and clear tail */
|
||||||
static void redraw(int y, int back_cursor)
|
static void redraw(int y, int back_cursor)
|
||||||
{
|
{
|
||||||
if (y > 0) /* up to start y */
|
if (y > 0) /* up to start y */
|
||||||
printf("\033[%dA", y);
|
printf("\033[%dA", y);
|
||||||
putchar('\r');
|
putchar('\r');
|
||||||
put_prompt();
|
put_prompt();
|
||||||
input_end(); /* rewrite */
|
input_end(); /* rewrite */
|
||||||
printf("\033[J"); /* destroy tail after cursor */
|
printf("\033[J"); /* destroy tail after cursor */
|
||||||
input_backward(back_cursor);
|
input_backward(back_cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -456,9 +461,9 @@ static void input_delete(void)
|
||||||
|
|
||||||
strcpy(command_ps + j, command_ps + j + 1);
|
strcpy(command_ps + j, command_ps + j + 1);
|
||||||
len--;
|
len--;
|
||||||
input_end(); /* rewtite new line */
|
input_end(); /* rewtite new line */
|
||||||
cmdedit_set_out_char(0); /* destroy end char */
|
cmdedit_set_out_char(0); /* destroy end char */
|
||||||
input_backward(cursor - j); /* back to old pos cursor */
|
input_backward(cursor - j); /* back to old pos cursor */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Delete the char in back of the cursor */
|
/* Delete the char in back of the cursor */
|
||||||
|
@ -527,9 +532,9 @@ static void cmdedit_init(void)
|
||||||
#endif
|
#endif
|
||||||
my_uid = getuid();
|
my_uid = getuid();
|
||||||
my_gid = getgid();
|
my_gid = getgid();
|
||||||
#endif /* CONFIG_FEATURE_COMMAND_TAB_COMPLETION */
|
#endif /* CONFIG_FEATURE_COMMAND_TAB_COMPLETION */
|
||||||
handlers_sets |= SET_ATEXIT;
|
handlers_sets |= SET_ATEXIT;
|
||||||
atexit(cmdedit_reset_term); /* be sure to do this only once */
|
atexit(cmdedit_reset_term); /* be sure to do this only once */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -553,35 +558,35 @@ static char **username_tab_completion(char *ud, int *num_matches)
|
||||||
char *temp;
|
char *temp;
|
||||||
|
|
||||||
|
|
||||||
ud++; /* ~user/... to user/... */
|
ud++; /* ~user/... to user/... */
|
||||||
userlen = strlen(ud);
|
userlen = strlen(ud);
|
||||||
|
|
||||||
if (num_matches == 0) { /* "~/..." or "~user/..." */
|
if (num_matches == 0) { /* "~/..." or "~user/..." */
|
||||||
char *sav_ud = ud - 1;
|
char *sav_ud = ud - 1;
|
||||||
char *home = 0;
|
char *home = 0;
|
||||||
|
|
||||||
if (*ud == '/') { /* "~/..." */
|
if (*ud == '/') { /* "~/..." */
|
||||||
home = home_pwd_buf;
|
home = home_pwd_buf;
|
||||||
} else {
|
} else {
|
||||||
/* "~user/..." */
|
/* "~user/..." */
|
||||||
temp = strchr(ud, '/');
|
temp = strchr(ud, '/');
|
||||||
*temp = 0; /* ~user\0 */
|
*temp = 0; /* ~user\0 */
|
||||||
entry = getpwnam(ud);
|
entry = getpwnam(ud);
|
||||||
*temp = '/'; /* restore ~user/... */
|
*temp = '/'; /* restore ~user/... */
|
||||||
ud = temp;
|
ud = temp;
|
||||||
if (entry)
|
if (entry)
|
||||||
home = entry->pw_dir;
|
home = entry->pw_dir;
|
||||||
}
|
}
|
||||||
if (home) {
|
if (home) {
|
||||||
if ((userlen + strlen(home) + 1) < BUFSIZ) {
|
if ((userlen + strlen(home) + 1) < BUFSIZ) {
|
||||||
char temp2[BUFSIZ]; /* argument size */
|
char temp2[BUFSIZ]; /* argument size */
|
||||||
|
|
||||||
/* /home/user/... */
|
/* /home/user/... */
|
||||||
sprintf(temp2, "%s%s", home, ud);
|
sprintf(temp2, "%s%s", home, ud);
|
||||||
strcpy(sav_ud, temp2);
|
strcpy(sav_ud, temp2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0; /* void, result save to argument :-) */
|
return 0; /* void, result save to argument :-) */
|
||||||
} else {
|
} else {
|
||||||
/* "~[^/]*" */
|
/* "~[^/]*" */
|
||||||
char **matches = (char **) NULL;
|
char **matches = (char **) NULL;
|
||||||
|
@ -593,7 +598,7 @@ static char **username_tab_completion(char *ud, int *num_matches)
|
||||||
/* Null usernames should result in all users as possible completions. */
|
/* Null usernames should result in all users as possible completions. */
|
||||||
if ( /*!userlen || */ !strncmp(ud, entry->pw_name, userlen)) {
|
if ( /*!userlen || */ !strncmp(ud, entry->pw_name, userlen)) {
|
||||||
|
|
||||||
bb_xasprintf(&temp, "~%s/", entry->pw_name);
|
bb_xasprintf(&temp, "~%s/", entry->pw_name);
|
||||||
matches = xrealloc(matches, (nm + 1) * sizeof(char *));
|
matches = xrealloc(matches, (nm + 1) * sizeof(char *));
|
||||||
|
|
||||||
matches[nm++] = temp;
|
matches[nm++] = temp;
|
||||||
|
@ -605,7 +610,7 @@ static char **username_tab_completion(char *ud, int *num_matches)
|
||||||
return (matches);
|
return (matches);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_FEATURE_COMMAND_USERNAME_COMPLETION */
|
#endif /* CONFIG_FEATURE_COMMAND_USERNAME_COMPLETION */
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
FIND_EXE_ONLY = 0,
|
FIND_EXE_ONLY = 0,
|
||||||
|
@ -630,11 +635,11 @@ static int path_parse(char ***p, int flags)
|
||||||
npth = 0;
|
npth = 0;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
npth++; /* count words is + 1 count ':' */
|
npth++; /* count words is + 1 count ':' */
|
||||||
tmp = strchr(tmp, ':');
|
tmp = strchr(tmp, ':');
|
||||||
if (tmp) {
|
if (tmp) {
|
||||||
if (*++tmp == 0)
|
if (*++tmp == 0)
|
||||||
break; /* :<empty> */
|
break; /* :<empty> */
|
||||||
} else
|
} else
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -643,17 +648,17 @@ static int path_parse(char ***p, int flags)
|
||||||
|
|
||||||
tmp = pth;
|
tmp = pth;
|
||||||
(*p)[0] = bb_xstrdup(tmp);
|
(*p)[0] = bb_xstrdup(tmp);
|
||||||
npth = 1; /* count words is + 1 count ':' */
|
npth = 1; /* count words is + 1 count ':' */
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
tmp = strchr(tmp, ':');
|
tmp = strchr(tmp, ':');
|
||||||
if (tmp) {
|
if (tmp) {
|
||||||
(*p)[0][(tmp - pth)] = 0; /* ':' -> '\0' */
|
(*p)[0][(tmp - pth)] = 0; /* ':' -> '\0' */
|
||||||
if (*++tmp == 0)
|
if (*++tmp == 0)
|
||||||
break; /* :<empty> */
|
break; /* :<empty> */
|
||||||
} else
|
} else
|
||||||
break;
|
break;
|
||||||
(*p)[npth++] = &(*p)[0][(tmp - pth)]; /* p[next]=p[0][&'\0'+1] */
|
(*p)[npth++] = &(*p)[0][(tmp - pth)]; /* p[next]=p[0][&'\0'+1] */
|
||||||
}
|
}
|
||||||
|
|
||||||
return npth;
|
return npth;
|
||||||
|
@ -703,20 +708,20 @@ static char **exe_n_cwd_tab_completion(char *command, int *num_matches,
|
||||||
/* set dir only */
|
/* set dir only */
|
||||||
dirbuf[(pfind - command) + 1] = 0;
|
dirbuf[(pfind - command) + 1] = 0;
|
||||||
#ifdef CONFIG_FEATURE_COMMAND_USERNAME_COMPLETION
|
#ifdef CONFIG_FEATURE_COMMAND_USERNAME_COMPLETION
|
||||||
if (dirbuf[0] == '~') /* ~/... or ~user/... */
|
if (dirbuf[0] == '~') /* ~/... or ~user/... */
|
||||||
username_tab_completion(dirbuf, 0);
|
username_tab_completion(dirbuf, 0);
|
||||||
#endif
|
#endif
|
||||||
/* "strip" dirname in command */
|
/* "strip" dirname in command */
|
||||||
pfind++;
|
pfind++;
|
||||||
|
|
||||||
paths[0] = dirbuf;
|
paths[0] = dirbuf;
|
||||||
npaths = 1; /* only 1 dir */
|
npaths = 1; /* only 1 dir */
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < npaths; i++) {
|
for (i = 0; i < npaths; i++) {
|
||||||
|
|
||||||
dir = opendir(paths[i]);
|
dir = opendir(paths[i]);
|
||||||
if (!dir) /* Don't print an error */
|
if (!dir) /* Don't print an error */
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
while ((next = readdir(dir)) != NULL) {
|
while ((next = readdir(dir)) != NULL) {
|
||||||
|
@ -728,7 +733,7 @@ static char **exe_n_cwd_tab_completion(char *command, int *num_matches,
|
||||||
/* not see .name without .match */
|
/* not see .name without .match */
|
||||||
if (*str_found == '.' && *pfind == 0) {
|
if (*str_found == '.' && *pfind == 0) {
|
||||||
if (*paths[i] == '/' && paths[i][1] == 0
|
if (*paths[i] == '/' && paths[i][1] == 0
|
||||||
&& str_found[1] == 0) str_found = ""; /* only "/" */
|
&& str_found[1] == 0) str_found = ""; /* only "/" */
|
||||||
else
|
else
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -738,7 +743,7 @@ static char **exe_n_cwd_tab_completion(char *command, int *num_matches,
|
||||||
goto cont;
|
goto cont;
|
||||||
/* find with dirs ? */
|
/* find with dirs ? */
|
||||||
if (paths[i] != dirbuf)
|
if (paths[i] != dirbuf)
|
||||||
strcpy(found, next->d_name); /* only name */
|
strcpy(found, next->d_name); /* only name */
|
||||||
if (S_ISDIR(st.st_mode)) {
|
if (S_ISDIR(st.st_mode)) {
|
||||||
/* name is directory */
|
/* name is directory */
|
||||||
str_found = found;
|
str_found = found;
|
||||||
|
@ -764,7 +769,7 @@ cont:
|
||||||
closedir(dir);
|
closedir(dir);
|
||||||
}
|
}
|
||||||
if (paths != path1) {
|
if (paths != path1) {
|
||||||
free(paths[0]); /* allocated memory only in first member */
|
free(paths[0]); /* allocated memory only in first member */
|
||||||
free(paths);
|
free(paths);
|
||||||
}
|
}
|
||||||
*num_matches = nm;
|
*num_matches = nm;
|
||||||
|
@ -796,7 +801,7 @@ static int find_match(char *matchBuf, int *len_with_quotes)
|
||||||
for (i = 0;; i++) {
|
for (i = 0;; i++) {
|
||||||
int_buf[i] = (int) ((unsigned char) matchBuf[i]);
|
int_buf[i] = (int) ((unsigned char) matchBuf[i]);
|
||||||
if (int_buf[i] == 0) {
|
if (int_buf[i] == 0) {
|
||||||
pos_buf[i] = -1; /* indicator end line */
|
pos_buf[i] = -1; /* indicator end line */
|
||||||
break;
|
break;
|
||||||
} else
|
} else
|
||||||
pos_buf[i] = i;
|
pos_buf[i] = i;
|
||||||
|
@ -809,7 +814,7 @@ static int find_match(char *matchBuf, int *len_with_quotes)
|
||||||
int_buf[j] |= QUOT;
|
int_buf[j] |= QUOT;
|
||||||
i++;
|
i++;
|
||||||
#ifdef CONFIG_FEATURE_NONPRINTABLE_INVERSE_PUT
|
#ifdef CONFIG_FEATURE_NONPRINTABLE_INVERSE_PUT
|
||||||
if (matchBuf[i] == '\t') /* algorithm equivalent */
|
if (matchBuf[i] == '\t') /* algorithm equivalent */
|
||||||
int_buf[j] = ' ' | QUOT;
|
int_buf[j] = ' ' | QUOT;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -852,7 +857,7 @@ static int find_match(char *matchBuf, int *len_with_quotes)
|
||||||
}
|
}
|
||||||
if (command_mode) {
|
if (command_mode) {
|
||||||
collapse_pos(0, i + command_mode);
|
collapse_pos(0, i + command_mode);
|
||||||
i = -1; /* hack incremet */
|
i = -1; /* hack incremet */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* collapse `command...` */
|
/* collapse `command...` */
|
||||||
|
@ -869,11 +874,11 @@ static int find_match(char *matchBuf, int *len_with_quotes)
|
||||||
collapse_pos(0, i + 1);
|
collapse_pos(0, i + 1);
|
||||||
break;
|
break;
|
||||||
} else
|
} else
|
||||||
i--; /* hack incremet */
|
i--; /* hack incremet */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* collapse (command...(command...)...) or {command...{command...}...} */
|
/* collapse (command...(command...)...) or {command...{command...}...} */
|
||||||
c = 0; /* "recursive" level */
|
c = 0; /* "recursive" level */
|
||||||
c2 = 0;
|
c2 = 0;
|
||||||
for (i = 0; int_buf[i]; i++)
|
for (i = 0; int_buf[i]; i++)
|
||||||
if (int_buf[i] == '(' || int_buf[i] == '{') {
|
if (int_buf[i] == '(' || int_buf[i] == '{') {
|
||||||
|
@ -882,7 +887,7 @@ static int find_match(char *matchBuf, int *len_with_quotes)
|
||||||
else
|
else
|
||||||
c2++;
|
c2++;
|
||||||
collapse_pos(0, i + 1);
|
collapse_pos(0, i + 1);
|
||||||
i = -1; /* hack incremet */
|
i = -1; /* hack incremet */
|
||||||
}
|
}
|
||||||
for (i = 0; pos_buf[i] >= 0 && (c > 0 || c2 > 0); i++)
|
for (i = 0; pos_buf[i] >= 0 && (c > 0 || c2 > 0); i++)
|
||||||
if ((int_buf[i] == ')' && c > 0) || (int_buf[i] == '}' && c2 > 0)) {
|
if ((int_buf[i] == ')' && c > 0) || (int_buf[i] == '}' && c2 > 0)) {
|
||||||
|
@ -891,7 +896,7 @@ static int find_match(char *matchBuf, int *len_with_quotes)
|
||||||
else
|
else
|
||||||
c2--;
|
c2--;
|
||||||
collapse_pos(0, i + 1);
|
collapse_pos(0, i + 1);
|
||||||
i = -1; /* hack incremet */
|
i = -1; /* hack incremet */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* skip first not quote space */
|
/* skip first not quote space */
|
||||||
|
@ -991,7 +996,7 @@ static void input_tab(int *lastWasTab)
|
||||||
static int num_matches;
|
static int num_matches;
|
||||||
static char **matches;
|
static char **matches;
|
||||||
|
|
||||||
if (lastWasTab == 0) { /* free all memory */
|
if (lastWasTab == 0) { /* free all memory */
|
||||||
if (matches) {
|
if (matches) {
|
||||||
while (num_matches > 0)
|
while (num_matches > 0)
|
||||||
free(matches[--num_matches]);
|
free(matches[--num_matches]);
|
||||||
|
@ -1008,7 +1013,7 @@ static void input_tab(int *lastWasTab)
|
||||||
int find_type;
|
int find_type;
|
||||||
int recalc_pos;
|
int recalc_pos;
|
||||||
|
|
||||||
*lastWasTab = TRUE; /* flop trigger */
|
*lastWasTab = TRUE; /* flop trigger */
|
||||||
|
|
||||||
/* Make a local copy of the string -- up
|
/* Make a local copy of the string -- up
|
||||||
* to the position of the cursor */
|
* to the position of the cursor */
|
||||||
|
@ -1061,7 +1066,7 @@ static void input_tab(int *lastWasTab)
|
||||||
|
|
||||||
beep();
|
beep();
|
||||||
if (!matches)
|
if (!matches)
|
||||||
return; /* not found */
|
return; /* not found */
|
||||||
/* sort */
|
/* sort */
|
||||||
qsort(matches, num_matches, sizeof(char *), match_compare);
|
qsort(matches, num_matches, sizeof(char *), match_compare);
|
||||||
|
|
||||||
|
@ -1073,11 +1078,11 @@ static void input_tab(int *lastWasTab)
|
||||||
*tmp1 = 0;
|
*tmp1 = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (*tmp == 0) { /* have unique */
|
if (*tmp == 0) { /* have unique */
|
||||||
free(tmp);
|
free(tmp);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else { /* one match */
|
} else { /* one match */
|
||||||
tmp = matches[0];
|
tmp = matches[0];
|
||||||
/* for next completion current found */
|
/* for next completion current found */
|
||||||
*lastWasTab = FALSE;
|
*lastWasTab = FALSE;
|
||||||
|
@ -1111,7 +1116,7 @@ static void input_tab(int *lastWasTab)
|
||||||
* just hit TAB again, print a list of all the
|
* just hit TAB again, print a list of all the
|
||||||
* available choices... */
|
* available choices... */
|
||||||
if (matches && num_matches > 0) {
|
if (matches && num_matches > 0) {
|
||||||
int sav_cursor = cursor; /* change goto_new_line() */
|
int sav_cursor = cursor; /* change goto_new_line() */
|
||||||
|
|
||||||
/* Go to the next line */
|
/* Go to the next line */
|
||||||
goto_new_line();
|
goto_new_line();
|
||||||
|
@ -1120,7 +1125,7 @@ static void input_tab(int *lastWasTab)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_FEATURE_COMMAND_TAB_COMPLETION */
|
#endif /* CONFIG_FEATURE_COMMAND_TAB_COMPLETION */
|
||||||
|
|
||||||
#if MAX_HISTORY >= 1
|
#if MAX_HISTORY >= 1
|
||||||
static void get_previous_history(void)
|
static void get_previous_history(void)
|
||||||
|
@ -1230,7 +1235,7 @@ int cmdedit_read_input(char *prompt, char command[BUFSIZ])
|
||||||
unsigned char c = 0;
|
unsigned char c = 0;
|
||||||
|
|
||||||
/* prepare before init handlers */
|
/* prepare before init handlers */
|
||||||
cmdedit_y = 0; /* quasireal y, not true work if line > xt*yt */
|
cmdedit_y = 0; /* quasireal y, not true work if line > xt*yt */
|
||||||
len = 0;
|
len = 0;
|
||||||
command_ps = command;
|
command_ps = command;
|
||||||
|
|
||||||
|
@ -1261,7 +1266,7 @@ int cmdedit_read_input(char *prompt, char command[BUFSIZ])
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
|
|
||||||
fflush(stdout); /* buffered out to fast */
|
fflush(stdout); /* buffered out to fast */
|
||||||
|
|
||||||
if (safe_read(0, &c, 1) < 1)
|
if (safe_read(0, &c, 1) < 1)
|
||||||
/* if we can't read input then exit */
|
/* if we can't read input then exit */
|
||||||
|
@ -1287,8 +1292,12 @@ int cmdedit_read_input(char *prompt, char command[BUFSIZ])
|
||||||
goto_new_line();
|
goto_new_line();
|
||||||
command[0] = 0;
|
command[0] = 0;
|
||||||
len = 0;
|
len = 0;
|
||||||
|
#if !defined(CONFIG_ASH)
|
||||||
lastWasTab = FALSE;
|
lastWasTab = FALSE;
|
||||||
put_prompt();
|
put_prompt();
|
||||||
|
#else
|
||||||
|
break_out = 2;
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
/* Control-d -- Delete one character, or exit
|
/* Control-d -- Delete one character, or exit
|
||||||
|
@ -1334,7 +1343,7 @@ prepare_to_die:
|
||||||
break;
|
break;
|
||||||
case 12:
|
case 12:
|
||||||
/* Control-l -- clear screen */
|
/* Control-l -- clear screen */
|
||||||
printf("\033[H");
|
printf("\033[H");
|
||||||
redraw(0, len-cursor);
|
redraw(0, len-cursor);
|
||||||
break;
|
break;
|
||||||
#if MAX_HISTORY >= 1
|
#if MAX_HISTORY >= 1
|
||||||
|
@ -1371,7 +1380,7 @@ prepare_to_die:
|
||||||
}
|
}
|
||||||
switch (c) {
|
switch (c) {
|
||||||
#ifdef CONFIG_FEATURE_COMMAND_TAB_COMPLETION
|
#ifdef CONFIG_FEATURE_COMMAND_TAB_COMPLETION
|
||||||
case '\t': /* Alt-Tab */
|
case '\t': /* Alt-Tab */
|
||||||
|
|
||||||
input_tab(&lastWasTab);
|
input_tab(&lastWasTab);
|
||||||
break;
|
break;
|
||||||
|
@ -1433,7 +1442,7 @@ rewrite_line:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
default: /* If it's regular input, do the normal thing */
|
default: /* If it's regular input, do the normal thing */
|
||||||
#ifdef CONFIG_FEATURE_NONPRINTABLE_INVERSE_PUT
|
#ifdef CONFIG_FEATURE_NONPRINTABLE_INVERSE_PUT
|
||||||
/* Control-V -- Add non-printable symbol */
|
/* Control-V -- Add non-printable symbol */
|
||||||
if (c == 22) {
|
if (c == 22) {
|
||||||
|
@ -1445,19 +1454,19 @@ rewrite_line:
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
if (!Isprint(c)) /* Skip non-printable characters */
|
if (!Isprint(c)) /* Skip non-printable characters */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (len >= (BUFSIZ - 2)) /* Need to leave space for enter */
|
if (len >= (BUFSIZ - 2)) /* Need to leave space for enter */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
len++;
|
len++;
|
||||||
|
|
||||||
if (cursor == (len - 1)) { /* Append if at the end of the line */
|
if (cursor == (len - 1)) { /* Append if at the end of the line */
|
||||||
*(command + cursor) = c;
|
*(command + cursor) = c;
|
||||||
*(command + cursor + 1) = 0;
|
*(command + cursor + 1) = 0;
|
||||||
cmdedit_set_out_char(0);
|
cmdedit_set_out_char(0);
|
||||||
} else { /* Insert otherwise */
|
} else { /* Insert otherwise */
|
||||||
int sc = cursor;
|
int sc = cursor;
|
||||||
|
|
||||||
memmove(command + sc + 1, command + sc, len - sc);
|
memmove(command + sc + 1, command + sc, len - sc);
|
||||||
|
@ -1471,7 +1480,7 @@ rewrite_line:
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (break_out) /* Enter is the command terminator, no more input. */
|
if (break_out) /* Enter is the command terminator, no more input. */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (c != '\t')
|
if (c != '\t')
|
||||||
|
@ -1486,7 +1495,7 @@ rewrite_line:
|
||||||
/* cleanup may be saved current command line */
|
/* cleanup may be saved current command line */
|
||||||
free(history[MAX_HISTORY]);
|
free(history[MAX_HISTORY]);
|
||||||
history[MAX_HISTORY] = 0;
|
history[MAX_HISTORY] = 0;
|
||||||
if (len) { /* no put empty line */
|
if (len) { /* no put empty line */
|
||||||
int i = n_history;
|
int i = n_history;
|
||||||
/* After max history, remove the oldest command */
|
/* After max history, remove the oldest command */
|
||||||
if (i >= MAX_HISTORY) {
|
if (i >= MAX_HISTORY) {
|
||||||
|
@ -1508,23 +1517,27 @@ rewrite_line:
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif /* MAX_HISTORY >= 1 */
|
#endif /* MAX_HISTORY >= 1 */
|
||||||
if(break_out>0) {
|
if(break_out == 1) {
|
||||||
command[len++] = '\n'; /* set '\n' */
|
command[len++] = '\n'; /* set '\n' */
|
||||||
command[len] = 0;
|
command[len] = 0;
|
||||||
}
|
}
|
||||||
#if defined(CONFIG_FEATURE_CLEAN_UP) && defined(CONFIG_FEATURE_COMMAND_TAB_COMPLETION)
|
#if defined(CONFIG_FEATURE_CLEAN_UP) && defined(CONFIG_FEATURE_COMMAND_TAB_COMPLETION)
|
||||||
input_tab(0); /* strong free */
|
input_tab(0); /* strong free */
|
||||||
#endif
|
#endif
|
||||||
#if defined(CONFIG_FEATURE_SH_FANCY_PROMPT)
|
#if defined(CONFIG_FEATURE_SH_FANCY_PROMPT)
|
||||||
free(cmdedit_prompt);
|
free(cmdedit_prompt);
|
||||||
#endif
|
#endif
|
||||||
cmdedit_reset_term();
|
cmdedit_reset_term();
|
||||||
|
#if !defined(CONFIG_ASH)
|
||||||
return len;
|
return len;
|
||||||
|
#else
|
||||||
|
return break_out < 0 ? break_out : len;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* CONFIG_FEATURE_COMMAND_EDITING */
|
#endif /* CONFIG_FEATURE_COMMAND_EDITING */
|
||||||
|
|
||||||
|
|
||||||
#ifdef TEST
|
#ifdef TEST
|
||||||
|
@ -1565,4 +1578,4 @@ int main(int argc, char **argv)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* TEST */
|
#endif /* TEST */
|
||||||
|
|
Loading…
Reference in New Issue