* 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:
parent
8b4d50358e
commit
9dd92c7315
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue