Some more stuff.

-Erik
This commit is contained in:
Erik Andersen 2000-03-19 05:28:55 +00:00
parent 6c41c44898
commit c7c634bd88
8 changed files with 976 additions and 919 deletions

179
cmdedit.c
View File

@ -1,3 +1,4 @@
/* vi: set sw=4 ts=4: */
/*
* Termios command line History and Editting for NetBSD sh (ash)
* Copyright (c) 1999
@ -40,8 +41,6 @@
#include <ctype.h>
#include <signal.h>
#include "cmdedit.h"
#define MAX_HISTORY 15 /* Maximum length of the linked list for the command line history */
@ -95,6 +94,7 @@ int xwrite(int fd, char *buf, int nbytes)
int xioctl(int fd, unsigned long request, char *arg)
{
int i;
while ((i = ioctl(fd, request, arg)) == -1 && errno == EINTR);
return i;
}
@ -177,20 +177,27 @@ void input_backspace(int outputFd, int *cursor, int *len)
}
}
char **username_completion_matches( char* matchBuf)
char** username_completion_matches(char* command, int *num_matches)
{
char **matches = (char **) NULL;
*num_matches=0;
fprintf(stderr, "\nin username_completion_matches\n");
return ( (char**) NULL);
return (matches);
}
char **command_completion_matches( char* matchBuf)
char** find_path_executable_n_cwd_matches(char* command, int *num_matches)
{
fprintf(stderr, "\nin command_completion_matches\n");
return ( (char**) NULL);
}
char **directory_completion_matches( char* matchBuf)
{
fprintf(stderr, "\nin directory_completion_matches\n");
return ( (char**) NULL);
char **matches = (char **) NULL;
matches = malloc(sizeof(char*)*100);
matches[0] = malloc(sizeof(char)*50);
matches[1] = malloc(sizeof(char)*50);
sprintf(matches[0], "Hello");
sprintf(matches[1], "Howdy");
*num_matches=2;
// fprintf(stderr, "\nin find_path_executable_n_cwd_matches\n");
return (matches);
}
/*
@ -211,7 +218,7 @@ char **directory_completion_matches( char* matchBuf)
* TODO: implement TAB command completion. :)
*
*/
extern int cmdedit_read_input(int inputFd, int outputFd,
extern int cmdedit_read_input(char* prompt, int inputFd, int outputFd,
char command[BUFSIZ])
{
@ -222,7 +229,6 @@ extern int cmdedit_read_input(int inputFd, int outputFd,
int break_out = 0;
int ret = 0;
int lastWasTab = FALSE;
char **matches = (char **)NULL;
char c = 0;
struct history *hp = his_end;
@ -231,6 +237,7 @@ extern int cmdedit_read_input(int inputFd, int outputFd,
if (!reset_term) {
xioctl(inputFd, TCGETA, (void *) &old_term);
memcpy(&new_term, &old_term, sizeof(struct termio));
new_term.c_cc[VMIN] = 1;
new_term.c_cc[VTIME] = 0;
new_term.c_lflag &= ~ICANON; /* unbuffered input */
@ -301,87 +308,99 @@ extern int cmdedit_read_input(int inputFd, int outputFd,
case '\t':
{
/* Do TAB completion */
int in_command_position=0, ti=len-1;
static int num_matches=0;
static char **matches = (char **) NULL;
int pos = cursor;
if (lastWasTab == FALSE) {
char *tmp;
char *matchBuf;
char *tmp, *tmp1, *matchBuf;
/* For now, we will not bother with trying to distinguish
* whether the cursor is in/at a command extression -- we
* will always try all possable matches. If you don't like
* that, feel free to fix it.
*/
/* Make a local copy of the string -- up
* to the the position of the cursor */
matchBuf = (char *) calloc(BUFSIZ, sizeof(char));
strncpy(matchBuf, parsenextc, cursor);
tmp=matchBuf;
/* skip past any command seperator tokens */
while (*tmp && (tmp1=strpbrk(tmp, ";|&{(`")) != NULL) {
tmp=++tmp1;
/* skip any leading white space */
while (*tmp && isspace(*tmp))
++tmp;
}
/* skip any leading white space */
while (*tmp && isspace(*tmp))
++tmp;
/* Free up any memory already allocated */
if (matches) {
free(matches);
matches = (char **) NULL;
}
matchBuf = (char *) calloc(BUFSIZ, sizeof(char));
/* Make a local copy of the string -- up
* to the the position of the cursor */
strcpy( matchBuf, parsenextc);
matchBuf[cursor+1] = '\0';
fprintf(stderr, "matchBuf='%s'\n", matchBuf);
/* skip leading white space */
tmp = matchBuf;
while (*tmp && isspace(*tmp)) {
(tmp)++;
ti++;
}
/* Determine if this is a command word or not */
//while ((ti > -1) && (whitespace (matchBuf[ti]))) {
//printf("\nti=%d\n", ti);
// ti--;
// }
printf("\nti=%d\n", ti);
if (ti < 0) {
in_command_position++;
} else if (member(matchBuf[ti], ";|&{(`")) {
int this_char, prev_char;
in_command_position++;
/* Handle the two character tokens `>&', `<&', and `>|'.
We are not in a command position after one of these. */
this_char = matchBuf[ti];
prev_char = matchBuf[ti - 1];
if ((this_char == '&' && (prev_char == '<' || prev_char == '>')) ||
(this_char == '|' && prev_char == '>')) {
in_command_position = 0;
}
/* For now, do not bother with catching quoted
* expressions and marking them as not in command
* positions. Some other day. Or not.
*/
//else if (char_is_quoted (matchBuf, ti)) {
// in_command_position = 0;
//}
}
printf("\nin_command_position=%d\n", in_command_position);
/* If the word starts in `~', and there is no slash in the word,
* then try completing this word as a username. */
if (*matchBuf == '~' && !strchr (matchBuf, '/'))
matches = username_completion_matches(matchBuf);
if (*tmp == '~' && !strchr(tmp, '/'))
matches = username_completion_matches(tmp, &num_matches);
/* If this word is in a command position, then complete over possible
* command names, including aliases, built-ins, and executables. */
if (!matches && in_command_position) {
matches = command_completion_matches(matchBuf);
/* If we are attempting command completion and nothing matches,
* then try and match directories as a last resort... */
/* Try to match any executable in our patch, and everything
* in the current working directory that matches.
*/
if (!matches)
matches = directory_completion_matches(matchBuf);
}
matches = find_path_executable_n_cwd_matches(tmp, &num_matches);
} else {
printf("\nprinting match list\n");
if ( matches && num_matches>0 ) {
int i, col;
fprintf(stderr, "\nTabbing...\n");
/* Make a list of the matches */
col += xwrite(outputFd, "\n", 1);
for (i=0,col=0; i<num_matches; i++) {
col += xwrite(outputFd, prompt, strlen(matches[i]));
if (col > 60 && matches[i+1] != NULL) {
xwrite(outputFd, "\n", 1);
col = 0;
}
/* Rewrite the whole line (for debugging) */
for (; cursor > 0; cursor--)
xwrite(outputFd, "\b", 1);
}
xwrite(outputFd, "\n", 1);
len+=strlen(prompt);
fprintf(stderr, "len=%d\n", len);
/* Move to the beginning of the line */
input_home(outputFd, &len);
/* erase everything */
for (j = 0; j < len; j++)
xwrite(outputFd, " ", 1);
/* return to begining of line */
input_home(outputFd, &cursor);
/* Rewrite the prompt) */
xwrite(outputFd, prompt, strlen(prompt));
/* Rewrite the command */
len = strlen(parsenextc);
xwrite(outputFd, parsenextc, len);
cursor = len;
/* Move back to where the cursor used to be */
for (cursor=pos; cursor > 0; cursor--)
xwrite(outputFd, "\b", 1);
cursor = pos;
//fprintf(stderr, "\nprompt='%s'\n", prompt);
}
}
break;
}
case '\b':
@ -553,6 +572,7 @@ printf("\nin_command_position=%d\n", in_command_position);
/* No previous history */
h = his_front = malloc(sizeof(struct history));
h->n = malloc(sizeof(struct history));
h->p = NULL;
h->s = strdup(parsenextc);
h->n->p = h;
@ -563,6 +583,7 @@ printf("\nin_command_position=%d\n", in_command_position);
} else {
/* Add a new history command */
h->n = malloc(sizeof(struct history));
h->n->p = h;
h->n->n = NULL;
h->n->s = NULL;

View File

@ -12,6 +12,6 @@
*
*/
extern int cmdedit_read_input(int inputFd, int outputFd, char command[BUFSIZ]);
extern int cmdedit_read_input(char* prompt, int inputFd, int outputFd, char command[BUFSIZ]);
extern void cmdedit_init(void);

View File

@ -216,6 +216,12 @@ extern int check_wildcard_match(const char* text, const char* pattern);
extern long getNum (const char *cp);
extern pid_t findPidByName( char* pidName);
extern void *xmalloc (size_t size);
#ifdef BB_FEATURE_SH_COMMAND_EDITING
#include <stdio.h>
extern int cmdedit_read_input(char* prompt, int inputFd, int outputFd, char command[BUFSIZ]);
extern void cmdedit_init(void);
#endif
#if defined BB_INIT || defined BB_SYSLOGD
extern int device_open(char *device, int mode);
#endif

21
lash.c
View File

@ -39,10 +39,6 @@
#include <unistd.h>
#ifdef BB_FEATURE_SH_COMMAND_EDITING
#include "cmdedit.h"
#endif
#define JOB_STATUS_FORMAT "[%d] %-22s %.40s\n"
@ -123,8 +119,7 @@ static struct builtInCommand bltins[] = {
{"export", "Set environment variable", "export [VAR=value]", shell_export},
{"unset", "Unset environment variable", "unset VAR", shell_unset},
{".", "Source-in and run commands in a file", ". filename",
shell_source},
{".", "Source-in and run commands in a file", ". filename", shell_source},
{"help", "List shell built-in commands", "help", shell_help},
{NULL, NULL, NULL, NULL}
};
@ -396,11 +391,19 @@ static void checkJobs(struct jobSet *jobList)
static int getCommand(FILE * source, char *command)
{
if (source == stdin) {
fprintf(stdout, "BBSHELL %s %s", cwd, prompt);
fflush(stdout);
#ifdef BB_FEATURE_SH_COMMAND_EDITING
cmdedit_read_input(fileno(stdin), fileno(stdout), command);
int len;
char *promptStr;
len=fprintf(stdout, "BBSHELL %s %s", cwd, prompt);
fflush(stdout);
promptStr=(char*)malloc(sizeof(char)*(len+1));
sprintf(promptStr, "BBSHELL %s %s", cwd, prompt);
cmdedit_read_input(promptStr, fileno(stdin), fileno(stdout), command);
free( promptStr);
return 0;
#else
fprintf(stdout, "%s %s", cwd, prompt);
fflush(stdout);
#endif
}

21
sh.c
View File

@ -39,10 +39,6 @@
#include <unistd.h>
#ifdef BB_FEATURE_SH_COMMAND_EDITING
#include "cmdedit.h"
#endif
#define JOB_STATUS_FORMAT "[%d] %-22s %.40s\n"
@ -123,8 +119,7 @@ static struct builtInCommand bltins[] = {
{"export", "Set environment variable", "export [VAR=value]", shell_export},
{"unset", "Unset environment variable", "unset VAR", shell_unset},
{".", "Source-in and run commands in a file", ". filename",
shell_source},
{".", "Source-in and run commands in a file", ". filename", shell_source},
{"help", "List shell built-in commands", "help", shell_help},
{NULL, NULL, NULL, NULL}
};
@ -396,11 +391,19 @@ static void checkJobs(struct jobSet *jobList)
static int getCommand(FILE * source, char *command)
{
if (source == stdin) {
fprintf(stdout, "BBSHELL %s %s", cwd, prompt);
fflush(stdout);
#ifdef BB_FEATURE_SH_COMMAND_EDITING
cmdedit_read_input(fileno(stdin), fileno(stdout), command);
int len;
char *promptStr;
len=fprintf(stdout, "BBSHELL %s %s", cwd, prompt);
fflush(stdout);
promptStr=(char*)malloc(sizeof(char)*(len+1));
sprintf(promptStr, "BBSHELL %s %s", cwd, prompt);
cmdedit_read_input(promptStr, fileno(stdin), fileno(stdout), command);
free( promptStr);
return 0;
#else
fprintf(stdout, "%s %s", cwd, prompt);
fflush(stdout);
#endif
}

View File

@ -1,3 +1,4 @@
/* vi: set sw=4 ts=4: */
/*
* Termios command line History and Editting for NetBSD sh (ash)
* Copyright (c) 1999
@ -40,8 +41,6 @@
#include <ctype.h>
#include <signal.h>
#include "cmdedit.h"
#define MAX_HISTORY 15 /* Maximum length of the linked list for the command line history */
@ -95,6 +94,7 @@ int xwrite(int fd, char *buf, int nbytes)
int xioctl(int fd, unsigned long request, char *arg)
{
int i;
while ((i = ioctl(fd, request, arg)) == -1 && errno == EINTR);
return i;
}
@ -177,20 +177,27 @@ void input_backspace(int outputFd, int *cursor, int *len)
}
}
char **username_completion_matches( char* matchBuf)
char** username_completion_matches(char* command, int *num_matches)
{
char **matches = (char **) NULL;
*num_matches=0;
fprintf(stderr, "\nin username_completion_matches\n");
return ( (char**) NULL);
return (matches);
}
char **command_completion_matches( char* matchBuf)
char** find_path_executable_n_cwd_matches(char* command, int *num_matches)
{
fprintf(stderr, "\nin command_completion_matches\n");
return ( (char**) NULL);
}
char **directory_completion_matches( char* matchBuf)
{
fprintf(stderr, "\nin directory_completion_matches\n");
return ( (char**) NULL);
char **matches = (char **) NULL;
matches = malloc(sizeof(char*)*100);
matches[0] = malloc(sizeof(char)*50);
matches[1] = malloc(sizeof(char)*50);
sprintf(matches[0], "Hello");
sprintf(matches[1], "Howdy");
*num_matches=2;
// fprintf(stderr, "\nin find_path_executable_n_cwd_matches\n");
return (matches);
}
/*
@ -211,7 +218,7 @@ char **directory_completion_matches( char* matchBuf)
* TODO: implement TAB command completion. :)
*
*/
extern int cmdedit_read_input(int inputFd, int outputFd,
extern int cmdedit_read_input(char* prompt, int inputFd, int outputFd,
char command[BUFSIZ])
{
@ -222,7 +229,6 @@ extern int cmdedit_read_input(int inputFd, int outputFd,
int break_out = 0;
int ret = 0;
int lastWasTab = FALSE;
char **matches = (char **)NULL;
char c = 0;
struct history *hp = his_end;
@ -231,6 +237,7 @@ extern int cmdedit_read_input(int inputFd, int outputFd,
if (!reset_term) {
xioctl(inputFd, TCGETA, (void *) &old_term);
memcpy(&new_term, &old_term, sizeof(struct termio));
new_term.c_cc[VMIN] = 1;
new_term.c_cc[VTIME] = 0;
new_term.c_lflag &= ~ICANON; /* unbuffered input */
@ -301,87 +308,99 @@ extern int cmdedit_read_input(int inputFd, int outputFd,
case '\t':
{
/* Do TAB completion */
int in_command_position=0, ti=len-1;
static int num_matches=0;
static char **matches = (char **) NULL;
int pos = cursor;
if (lastWasTab == FALSE) {
char *tmp;
char *matchBuf;
char *tmp, *tmp1, *matchBuf;
/* For now, we will not bother with trying to distinguish
* whether the cursor is in/at a command extression -- we
* will always try all possable matches. If you don't like
* that, feel free to fix it.
*/
/* Make a local copy of the string -- up
* to the the position of the cursor */
matchBuf = (char *) calloc(BUFSIZ, sizeof(char));
strncpy(matchBuf, parsenextc, cursor);
tmp=matchBuf;
/* skip past any command seperator tokens */
while (*tmp && (tmp1=strpbrk(tmp, ";|&{(`")) != NULL) {
tmp=++tmp1;
/* skip any leading white space */
while (*tmp && isspace(*tmp))
++tmp;
}
/* skip any leading white space */
while (*tmp && isspace(*tmp))
++tmp;
/* Free up any memory already allocated */
if (matches) {
free(matches);
matches = (char **) NULL;
}
matchBuf = (char *) calloc(BUFSIZ, sizeof(char));
/* Make a local copy of the string -- up
* to the the position of the cursor */
strcpy( matchBuf, parsenextc);
matchBuf[cursor+1] = '\0';
fprintf(stderr, "matchBuf='%s'\n", matchBuf);
/* skip leading white space */
tmp = matchBuf;
while (*tmp && isspace(*tmp)) {
(tmp)++;
ti++;
}
/* Determine if this is a command word or not */
//while ((ti > -1) && (whitespace (matchBuf[ti]))) {
//printf("\nti=%d\n", ti);
// ti--;
// }
printf("\nti=%d\n", ti);
if (ti < 0) {
in_command_position++;
} else if (member(matchBuf[ti], ";|&{(`")) {
int this_char, prev_char;
in_command_position++;
/* Handle the two character tokens `>&', `<&', and `>|'.
We are not in a command position after one of these. */
this_char = matchBuf[ti];
prev_char = matchBuf[ti - 1];
if ((this_char == '&' && (prev_char == '<' || prev_char == '>')) ||
(this_char == '|' && prev_char == '>')) {
in_command_position = 0;
}
/* For now, do not bother with catching quoted
* expressions and marking them as not in command
* positions. Some other day. Or not.
*/
//else if (char_is_quoted (matchBuf, ti)) {
// in_command_position = 0;
//}
}
printf("\nin_command_position=%d\n", in_command_position);
/* If the word starts in `~', and there is no slash in the word,
* then try completing this word as a username. */
if (*matchBuf == '~' && !strchr (matchBuf, '/'))
matches = username_completion_matches(matchBuf);
if (*tmp == '~' && !strchr(tmp, '/'))
matches = username_completion_matches(tmp, &num_matches);
/* If this word is in a command position, then complete over possible
* command names, including aliases, built-ins, and executables. */
if (!matches && in_command_position) {
matches = command_completion_matches(matchBuf);
/* If we are attempting command completion and nothing matches,
* then try and match directories as a last resort... */
/* Try to match any executable in our patch, and everything
* in the current working directory that matches.
*/
if (!matches)
matches = directory_completion_matches(matchBuf);
}
matches = find_path_executable_n_cwd_matches(tmp, &num_matches);
} else {
printf("\nprinting match list\n");
if ( matches && num_matches>0 ) {
int i, col;
fprintf(stderr, "\nTabbing...\n");
/* Make a list of the matches */
col += xwrite(outputFd, "\n", 1);
for (i=0,col=0; i<num_matches; i++) {
col += xwrite(outputFd, prompt, strlen(matches[i]));
if (col > 60 && matches[i+1] != NULL) {
xwrite(outputFd, "\n", 1);
col = 0;
}
/* Rewrite the whole line (for debugging) */
for (; cursor > 0; cursor--)
xwrite(outputFd, "\b", 1);
}
xwrite(outputFd, "\n", 1);
len+=strlen(prompt);
fprintf(stderr, "len=%d\n", len);
/* Move to the beginning of the line */
input_home(outputFd, &len);
/* erase everything */
for (j = 0; j < len; j++)
xwrite(outputFd, " ", 1);
/* return to begining of line */
input_home(outputFd, &cursor);
/* Rewrite the prompt) */
xwrite(outputFd, prompt, strlen(prompt));
/* Rewrite the command */
len = strlen(parsenextc);
xwrite(outputFd, parsenextc, len);
cursor = len;
/* Move back to where the cursor used to be */
for (cursor=pos; cursor > 0; cursor--)
xwrite(outputFd, "\b", 1);
cursor = pos;
//fprintf(stderr, "\nprompt='%s'\n", prompt);
}
}
break;
}
case '\b':
@ -553,6 +572,7 @@ printf("\nin_command_position=%d\n", in_command_position);
/* No previous history */
h = his_front = malloc(sizeof(struct history));
h->n = malloc(sizeof(struct history));
h->p = NULL;
h->s = strdup(parsenextc);
h->n->p = h;
@ -563,6 +583,7 @@ printf("\nin_command_position=%d\n", in_command_position);
} else {
/* Add a new history command */
h->n = malloc(sizeof(struct history));
h->n->p = h;
h->n->n = NULL;
h->n->s = NULL;

View File

@ -12,6 +12,6 @@
*
*/
extern int cmdedit_read_input(int inputFd, int outputFd, char command[BUFSIZ]);
extern int cmdedit_read_input(char* prompt, int inputFd, int outputFd, char command[BUFSIZ]);
extern void cmdedit_init(void);

View File

@ -39,10 +39,6 @@
#include <unistd.h>
#ifdef BB_FEATURE_SH_COMMAND_EDITING
#include "cmdedit.h"
#endif
#define JOB_STATUS_FORMAT "[%d] %-22s %.40s\n"
@ -123,8 +119,7 @@ static struct builtInCommand bltins[] = {
{"export", "Set environment variable", "export [VAR=value]", shell_export},
{"unset", "Unset environment variable", "unset VAR", shell_unset},
{".", "Source-in and run commands in a file", ". filename",
shell_source},
{".", "Source-in and run commands in a file", ". filename", shell_source},
{"help", "List shell built-in commands", "help", shell_help},
{NULL, NULL, NULL, NULL}
};
@ -396,11 +391,19 @@ static void checkJobs(struct jobSet *jobList)
static int getCommand(FILE * source, char *command)
{
if (source == stdin) {
fprintf(stdout, "BBSHELL %s %s", cwd, prompt);
fflush(stdout);
#ifdef BB_FEATURE_SH_COMMAND_EDITING
cmdedit_read_input(fileno(stdin), fileno(stdout), command);
int len;
char *promptStr;
len=fprintf(stdout, "BBSHELL %s %s", cwd, prompt);
fflush(stdout);
promptStr=(char*)malloc(sizeof(char)*(len+1));
sprintf(promptStr, "BBSHELL %s %s", cwd, prompt);
cmdedit_read_input(promptStr, fileno(stdin), fileno(stdout), command);
free( promptStr);
return 0;
#else
fprintf(stdout, "%s %s", cwd, prompt);
fflush(stdout);
#endif
}