* com_history, com_alias, parser/cshpar.c, parser/complete.c:

Applied patch by Michael Widlok.  It fixes command completion and
	history list.  In the process, Michael also fixed a memory leak.
This commit is contained in:
arno 2000-11-07 17:49:18 +00:00
parent 8b4d50358e
commit 9dd92c7315
5 changed files with 83 additions and 67 deletions

View File

@ -1,3 +1,9 @@
2000-11-07 Arno W. Peters <A.W.Peters@ieee.org>
* com_history, com_alias, parser/cshpar.c, parser/complete.c:
Applied patch by Michael Widlok. It fixes command completion and
history list. In the process, Michael also fixed a memory leak.
2000-09-09 Arno W. Peters <A.W.Peters@ieee.org>
* commands.c: Use fourier.h.

View File

@ -51,11 +51,13 @@ asubst(wordlist *wlist)
/* MW. This function should not use cp_lastone, see cp_parse in cpshar.c
* Many things are deleted here and memory leak closed */
wordlist *
cp_doalias(wordlist *wlist)
{
int ntries;
wordlist *realw, *nwl, *nextc = NULL, *end = NULL;
wordlist *nwl, *nextc = NULL, *end = NULL;
wordlist *comm;
while (wlist && eq(wlist->wl_word, cp_csep))
@ -66,7 +68,6 @@ cp_doalias(wordlist *wlist)
* save a copy of what it really is and restore it after aliasing
* is done. We have to do tricky things do get around the problems
* with ; ... */
realw = wl_copy(cp_lastone->hi_wlist);
comm = wlist;
do {
end = comm->wl_prev;
@ -77,9 +78,7 @@ cp_doalias(wordlist *wlist)
nextc->wl_prev->wl_next = NULL;
break;
}
wl_free(cp_lastone->hi_wlist);
cp_lastone->hi_wlist = wl_copy(comm);
for (ntries = 21; ntries; ntries--) {
nwl = asubst(comm);
if (nwl == NULL)
@ -115,8 +114,6 @@ cp_doalias(wordlist *wlist)
}
} while (nextc);
wl_free(cp_lastone->hi_wlist);
cp_lastone->hi_wlist = realw;
return (wlist);
}
@ -130,14 +127,11 @@ cp_setalias(char *word, wordlist *wlist)
cp_unalias(word);
cp_addkword(CT_ALIASES, word);
if (cp_aliases == NULL) {
/* printf("first one...\n"); */
al = cp_aliases = alloc(struct alias);
al->al_next = NULL;
al->al_prev = NULL;
} else {
/* printf("inserting %s: %s ...\n", word, wlist->wl_word); */
for (al = cp_aliases; al->al_next; al = al->al_next) {
/* printf("checking %s...\n", al->al_name); */
if (strcmp(al->al_name, word) > 0)
break;
}
@ -165,9 +159,6 @@ cp_setalias(char *word, wordlist *wlist)
* keyword lookup is done the alias is evaluated. Make everything
* file completion, just in case... */
cp_addcomm(word, (long) 1, (long) 1, (long) 1, (long) 1);
/* printf("word %s, next = %s, prev = %s...\n", al->al_name,
al->al_next ? al->al_next->al_name : "(none)",
al->al_prev ? al->al_prev->al_name : "(none)"); */
return;
}

View File

@ -30,12 +30,12 @@ bool cp_didhsubst;
static struct histent *histlist = NULL;
static int histlength = 0;
/* First check for a ^ at the beginning
* of the line, and then search each word for !. Following this can be any
* of string, number, ?string, -number ; then there may be a word specifier,
* the same as csh, and then the : modifiers. For the :s modifier,
* the syntax is :sXoooXnnnX, where X is any character, and ooo and nnn are
* strings not containing X.
/* First check for a ^ at the beginning of the line, and then search
* each word for !. Following this can be any of string, number,
* ?string, -number ; then there may be a word specifier, the same as
* csh, and then the : modifiers. For the :s modifier, the syntax is
* :sXoooXnnnX, where X is any character, and ooo and nnn are strings
* not containing X.
*/
wordlist *
@ -328,9 +328,14 @@ hprefix(char *buf)
void
cp_addhistent(int event, wordlist *wlist)
{
if (cp_lastone && !cp_lastone->hi_wlist)
fprintf(cp_err, "Internal error: bad history list\n");
/* MW. This test is not needed if everything works right */
if (cp_lastone && !cp_lastone->hi_wlist)
fprintf(cp_err, "Internal error: bad history list\n"); */
if (cp_lastone == NULL) {
/* MW. the begging - initialize histlength*/
histlength = 1;
cp_lastone = histlist = alloc(struct histent);
cp_lastone->hi_prev = NULL;
} else {

View File

@ -73,7 +73,8 @@ static void printem(wordlist *wl);
static wordlist * cctowl(struct ccom *cc, bool sib);
static struct ccom * clookup(register char *word, struct ccom **dd, bool pref,
bool create);
static void cdelete(struct ccom *node);
/* MW. I need top node in cdelete */
static void cdelete(struct ccom *node, struct ccom **top);
#ifdef TIOCSTI
@ -87,10 +88,7 @@ cp_ccom(wordlist *wlist, char *buf, bool esc)
int i=0;
int j, arg;
/* buf = cp_unquote(copy(buf)); DG: ugly*/
s=cp_unquote(buf);/*DG*/
strcpy(buf,s);
tfree(s);
buf = cp_unquote(copy(buf));
cp_wstrip(buf);
if (wlist->wl_next) { /* Not the first word. */
cc = getccom(wlist->wl_word);
@ -197,7 +195,7 @@ static wordlist *
ccfilec(char *buf)
{
DIR *wdir;
char *lcomp, *dir,*copydir;
char *lcomp, *dir;
struct direct *de;
wordlist *wl = NULL, *t;
struct passwd *pw;
@ -234,10 +232,7 @@ ccfilec(char *buf)
*lcomp = '\0';
lcomp++;
if (*dir == cp_til) {
copydir=cp_tildexpand(dir);/*DG*/
/*dir = cp_tildexpand(dir); very bad the last reference is lost: memory leak*/
strcpy(dir,copydir);
tfree(copydir);
dir = cp_tildexpand(dir);
if (dir == NULL)
return (NULL);
}
@ -266,9 +261,10 @@ ccfilec(char *buf)
return (wl);
}
/* See what keywords or commands match the prefix. Check extra also for
* matches, if it is non-NULL. Return a wordlist which is in alphabetical
* order. Note that we have to call this once for each class.
/* See what keywords or commands match the prefix. Check extra also
* for matches, if it is non-NULL. Return a wordlist which is in
* alphabetical order. Note that we have to call this once for each
* class.
*/
static wordlist *
@ -288,8 +284,8 @@ ccmatch(char *word, struct ccom **dbase)
return (wl);
}
/* Print the words in the wordlist in columns. They are already sorted...
* This is a hard thing to do with wordlists...
/* Print the words in the wordlist in columns. They are already
* sorted... This is a hard thing to do with wordlists...
*/
static void
@ -389,8 +385,8 @@ cp_ccon(bool on)
ison = on;
/* Set the terminal up -- make escape the break character, and
* make sure we aren't in raw or cbreak mode. Hope the (void) ioctl's
* won't fail.
* make sure we aren't in raw or cbreak mode. Hope the (void)
* ioctl's won't fail.
*/
(void) ioctl(fileno(cp_in), TIOCGETC, (char *) &tbuf);
if (on)
@ -461,7 +457,8 @@ cp_comlook(char *word)
return (FALSE);
}
/* Add a command to the database, with the given keywords and filename flag. */
/* Add a command to the database, with the given keywords and filename
* flag. */
void
cp_addcomm(char *word, long int bits0, long int bits1, long int bits2, long int bits3)
@ -486,7 +483,7 @@ cp_remcomm(char *word)
cc = clookup(word, &commands, FALSE, FALSE);
if (cc)
cdelete(cc);
cdelete(cc, &commands);
return;
}
@ -516,13 +513,13 @@ cp_remkword(int class, char *word)
struct ccom *cc;
if ((class < 1) || (class >= NCLASSES)) {
fprintf(cp_err, "cp_addkword: Internal Error: bad class %d\n",
fprintf(cp_err, "cp_remkword: Internal Error: bad class %d\n",
class);
return;
}
cc = clookup(word, &keywords[class], FALSE, FALSE);
if (cc)
cdelete(cc);
cdelete(cc, &keywords[class]);
return;
}
@ -567,10 +564,10 @@ throwaway(struct ccom *dbase)
return;
}
/* Look up a word in the database. Because of the
* way the tree is set up, this also works for looking up all words with
* a given prefix (if the pref arg is TRUE). If create is TRUE, then the
* node is created if it doesn't already exist.
/* Look up a word in the database. Because of the way the tree is set
* up, this also works for looking up all words with a given prefix
* (if the pref arg is TRUE). If create is TRUE, then the node is
* created if it doesn't already exist.
*/
static struct ccom *
@ -580,9 +577,6 @@ clookup(register char *word, struct ccom **dd, bool pref, bool create)
int ind = 0, i;
char buf[BSIZE_SP];
/* printf("----- adding %s -----\n", word); */
/* prcc(); */
if (!place) {
/* This is the first time we were called. */
if (!create)
@ -648,7 +642,6 @@ clookup(register char *word, struct ccom **dd, bool pref, bool create)
/* place now points to that node that matches the word for
* ind + 1 characters.
*/
/* printf("place %s, word %s, ind %d\n", place->cc_name, word, ind); */
if (word[ind + 1]) { /* More to go... */
if (!place->cc_child) {
/* No children, maybe make one and go on. */
@ -681,16 +674,43 @@ clookup(register char *word, struct ccom **dd, bool pref, bool create)
}
/* Delete a node from the tree. Returns the new tree... */
/* MW. It is quite difficoult to free() everything right, but...
* Anyway this could be more optimal, I think */
static void
cdelete(struct ccom *node)
cdelete(struct ccom *node, struct ccom **top)
{
node->cc_invalid = 1;
tfree(node->cc_name);
tfree(node->cc_child);
tfree(node->cc_sibling);
tfree(node->cc_ysibling);
tfree(node->cc_parent);
return;
/* if cc_child exist only mark as deleted */
node->cc_invalid = 1;
if (node->cc_child)
return;
/* fix cc_sibling */
if (node->cc_sibling)
node->cc_sibling->cc_ysibling = node->cc_ysibling;
if (node->cc_ysibling)
node->cc_ysibling->cc_sibling = node->cc_sibling;
/* if we have cc_parent, check if it should not be removed too */
if (node->cc_parent) {
/* this node will be free() */
if (node->cc_parent->cc_child == node) {
if (node->cc_ysibling)
node->cc_parent->cc_child = node->cc_ysibling;
else
node->cc_parent->cc_child = node->cc_sibling;
}
if (node->cc_parent->cc_invalid == 1)
/* free parent only if it is invalid */
cdelete(node->cc_parent, top);
}
/* now free() everything and check the top */
if (node == *top)
*top = node->cc_sibling;
free(node->cc_name);
free(node);
return;
}

View File

@ -83,19 +83,13 @@ cp_parse(char *string)
}
/* Add the word list to the history. */
if (*wlist->wl_word)
/* MW. If string==NULL we do not have to do this, and then play
* with cp_lastone is not needed, but watch out cp_doalias */
if ((*wlist->wl_word) && !(string))
cp_addhistent(cp_event - 1, wlist);
wlist = cp_doalias(wlist);
pwlist(wlist, "After alias substitution");
if (string && cp_lastone) {
/* Don't put this one in... */
cp_lastone = cp_lastone->hi_prev;
if (cp_lastone)
cp_lastone->hi_next = NULL;
}
pwlist(wlist, "Returning ");
return (wlist);
}