Browse Source

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


			
			
				pre-master-46
			
			
		
arno 26 years ago
parent
commit
9dd92c7315
  1. 6
      src/frontend/ChangeLog
  2. 17
      src/frontend/com_alias.c
  3. 21
      src/frontend/com_history.c
  4. 94
      src/frontend/parser/complete.c
  5. 12
      src/frontend/parser/cshpar.c

6
src/frontend/ChangeLog

@ -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> 2000-09-09 Arno W. Peters <A.W.Peters@ieee.org>
* commands.c: Use fourier.h. * commands.c: Use fourier.h.

17
src/frontend/com_alias.c

@ -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 * wordlist *
cp_doalias(wordlist *wlist) cp_doalias(wordlist *wlist)
{ {
int ntries; int ntries;
wordlist *realw, *nwl, *nextc = NULL, *end = NULL;
wordlist *nwl, *nextc = NULL, *end = NULL;
wordlist *comm; wordlist *comm;
while (wlist && eq(wlist->wl_word, cp_csep)) 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 * 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 * is done. We have to do tricky things do get around the problems
* with ; ... */ * with ; ... */
realw = wl_copy(cp_lastone->hi_wlist);
comm = wlist; comm = wlist;
do { do {
end = comm->wl_prev; end = comm->wl_prev;
@ -77,9 +78,7 @@ cp_doalias(wordlist *wlist)
nextc->wl_prev->wl_next = NULL; nextc->wl_prev->wl_next = NULL;
break; break;
} }
wl_free(cp_lastone->hi_wlist);
cp_lastone->hi_wlist = wl_copy(comm);
for (ntries = 21; ntries; ntries--) { for (ntries = 21; ntries; ntries--) {
nwl = asubst(comm); nwl = asubst(comm);
if (nwl == NULL) if (nwl == NULL)
@ -115,8 +114,6 @@ cp_doalias(wordlist *wlist)
} }
} while (nextc); } while (nextc);
wl_free(cp_lastone->hi_wlist);
cp_lastone->hi_wlist = realw;
return (wlist); return (wlist);
} }
@ -130,14 +127,11 @@ cp_setalias(char *word, wordlist *wlist)
cp_unalias(word); cp_unalias(word);
cp_addkword(CT_ALIASES, word); cp_addkword(CT_ALIASES, word);
if (cp_aliases == NULL) { if (cp_aliases == NULL) {
/* printf("first one...\n"); */
al = cp_aliases = alloc(struct alias); al = cp_aliases = alloc(struct alias);
al->al_next = NULL; al->al_next = NULL;
al->al_prev = NULL; al->al_prev = NULL;
} else { } else {
/* printf("inserting %s: %s ...\n", word, wlist->wl_word); */
for (al = cp_aliases; al->al_next; al = al->al_next) { 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) if (strcmp(al->al_name, word) > 0)
break; break;
} }
@ -165,9 +159,6 @@ cp_setalias(char *word, wordlist *wlist)
* keyword lookup is done the alias is evaluated. Make everything * keyword lookup is done the alias is evaluated. Make everything
* file completion, just in case... */ * file completion, just in case... */
cp_addcomm(word, (long) 1, (long) 1, (long) 1, (long) 1); 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; return;
} }

21
src/frontend/com_history.c

@ -30,12 +30,12 @@ bool cp_didhsubst;
static struct histent *histlist = NULL; static struct histent *histlist = NULL;
static int histlength = 0; 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 * wordlist *
@ -328,9 +328,14 @@ hprefix(char *buf)
void void
cp_addhistent(int event, wordlist *wlist) 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) { if (cp_lastone == NULL) {
/* MW. the begging - initialize histlength*/
histlength = 1;
cp_lastone = histlist = alloc(struct histent); cp_lastone = histlist = alloc(struct histent);
cp_lastone->hi_prev = NULL; cp_lastone->hi_prev = NULL;
} else { } else {

94
src/frontend/parser/complete.c

@ -73,7 +73,8 @@ static void printem(wordlist *wl);
static wordlist * cctowl(struct ccom *cc, bool sib); static wordlist * cctowl(struct ccom *cc, bool sib);
static struct ccom * clookup(register char *word, struct ccom **dd, bool pref, static struct ccom * clookup(register char *word, struct ccom **dd, bool pref,
bool create); 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 #ifdef TIOCSTI
@ -87,10 +88,7 @@ cp_ccom(wordlist *wlist, char *buf, bool esc)
int i=0; int i=0;
int j, arg; 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); cp_wstrip(buf);
if (wlist->wl_next) { /* Not the first word. */ if (wlist->wl_next) { /* Not the first word. */
cc = getccom(wlist->wl_word); cc = getccom(wlist->wl_word);
@ -197,7 +195,7 @@ static wordlist *
ccfilec(char *buf) ccfilec(char *buf)
{ {
DIR *wdir; DIR *wdir;
char *lcomp, *dir,*copydir;
char *lcomp, *dir;
struct direct *de; struct direct *de;
wordlist *wl = NULL, *t; wordlist *wl = NULL, *t;
struct passwd *pw; struct passwd *pw;
@ -234,10 +232,7 @@ ccfilec(char *buf)
*lcomp = '\0'; *lcomp = '\0';
lcomp++; lcomp++;
if (*dir == cp_til) { 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) if (dir == NULL)
return (NULL); return (NULL);
} }
@ -266,9 +261,10 @@ ccfilec(char *buf)
return (wl); 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 * static wordlist *
@ -288,8 +284,8 @@ ccmatch(char *word, struct ccom **dbase)
return (wl); 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 static void
@ -389,8 +385,8 @@ cp_ccon(bool on)
ison = on; ison = on;
/* Set the terminal up -- make escape the break character, and /* 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); (void) ioctl(fileno(cp_in), TIOCGETC, (char *) &tbuf);
if (on) if (on)
@ -461,7 +457,8 @@ cp_comlook(char *word)
return (FALSE); 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 void
cp_addcomm(char *word, long int bits0, long int bits1, long int bits2, long int bits3) 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); cc = clookup(word, &commands, FALSE, FALSE);
if (cc) if (cc)
cdelete(cc);
cdelete(cc, &commands);
return; return;
} }
@ -516,13 +513,13 @@ cp_remkword(int class, char *word)
struct ccom *cc; struct ccom *cc;
if ((class < 1) || (class >= NCLASSES)) { 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); class);
return; return;
} }
cc = clookup(word, &keywords[class], FALSE, FALSE); cc = clookup(word, &keywords[class], FALSE, FALSE);
if (cc) if (cc)
cdelete(cc);
cdelete(cc, &keywords[class]);
return; return;
} }
@ -567,10 +564,10 @@ throwaway(struct ccom *dbase)
return; 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 * static struct ccom *
@ -580,9 +577,6 @@ clookup(register char *word, struct ccom **dd, bool pref, bool create)
int ind = 0, i; int ind = 0, i;
char buf[BSIZE_SP]; char buf[BSIZE_SP];
/* printf("----- adding %s -----\n", word); */
/* prcc(); */
if (!place) { if (!place) {
/* This is the first time we were called. */ /* This is the first time we were called. */
if (!create) 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 /* place now points to that node that matches the word for
* ind + 1 characters. * ind + 1 characters.
*/ */
/* printf("place %s, word %s, ind %d\n", place->cc_name, word, ind); */
if (word[ind + 1]) { /* More to go... */ if (word[ind + 1]) { /* More to go... */
if (!place->cc_child) { if (!place->cc_child) {
/* No children, maybe make one and go on. */ /* 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... */ /* 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 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;
} }

12
src/frontend/parser/cshpar.c

@ -83,19 +83,13 @@ cp_parse(char *string)
} }
/* Add the word list to the history. */ /* 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); cp_addhistent(cp_event - 1, wlist);
wlist = cp_doalias(wlist); wlist = cp_doalias(wlist);
pwlist(wlist, "After alias substitution"); 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 "); pwlist(wlist, "Returning ");
return (wlist); return (wlist);
} }

Loading…
Cancel
Save