zsh-workers
 help / color / mirror / code / Atom feed
* Reserved words and aliases
@ 1995-05-25 13:05 P.Stephenson
  1995-05-25 23:58 ` Richard Coleman
  0 siblings, 1 reply; 4+ messages in thread
From: P.Stephenson @ 1995-05-25 13:05 UTC (permalink / raw)
  To: Zsh hackers list

In a reply to Bart about the behaviour of exec (which didn't go to the
list since I forgot about the new reply behaviour), I pointed out that
exec couldn't be an alias, and said I couldn't be bothered to fix
this.

I lied.

The problem is a Z-shell Kludge (TM):  the aliases and reserved words
shared the same hash table.  The old behaviour was that making exec
an alias stopped the real exec from being recognised as a shell
reserved word and this couldn't be undone.

I could have fixed this by compounding the kludge, e.g. by adding an
extra flag if an alias was a reserved word that was aliased.  Instead
I decided to do it properly and put the reserved words in their own
hash table.  This enabled some minor data size optimisations at the
expense of some minor code increase.  It also opens the way in future
to turn off aliases as an option if that ever becomes necessary.

Since reswdtab is never altered, I made some attempt at finding a
suitable size: 23 seemed to be a reasonable trade off, though it
leaves five hash buckets empty.

There is the odd minor but reasonable change in behaviour, for example
compctl's alias flag won't produce reserved words any more (they still
appear for command completion and spell checking).

You can now do

% alias exec="((SHLVL++, SAVEHIST=0)); exec"

if you really want.

*** Src/builtin.c.ali	Fri May 19 10:10:25 1995
--- Src/builtin.c	Thu May 25 13:33:19 1995
***************
*** 3292,3297 ****
--- 3292,3298 ----
  {
      struct cmdnam *chn;
      struct alias *a;
+     struct reswd *rw;
      int retval = 0;
      int csh = ops[(int)'c'], all = ops[(int)'a'];
      int v = ops['v'] || csh;
***************
*** 3315,3321 ****
  	    }
  	    if (!ops['p']) {
  		/* -p option is for path search only.  We're not using it, so
! 		search for reserved words, aliases, builtins and functions. */
  		n = aliastab->hsize;
  		for (i = 0; i < n; i++) {
  		    for (a = (struct alias *)aliastab->nodes[i]; a;
--- 3316,3322 ----
  	    }
  	    if (!ops['p']) {
  		/* -p option is for path search only.  We're not using it, so
! 		search for aliases ... */
  		n = aliastab->hsize;
  		for (i = 0; i < n; i++) {
  		    for (a = (struct alias *)aliastab->nodes[i]; a;
***************
*** 3323,3332 ****
  			/* Going through the alias table.  Display a match if
  			there is one. */
  			if (a->nam && domatch(a->nam, com, 0)) {
! 			    if (a->cmd < 0)
! 				printf((csh) ? "%s: shell reserved word\n" :
! 				       (v) ? "%s is a reserved word\n" : "%s\n", a->nam);
! 			    else if (!v)
  				puts(a->text);
  			    else if (a->cmd)
  				printf((csh) ? "%s: aliased to %s\n" :
--- 3324,3330 ----
  			/* Going through the alias table.  Display a match if
  			there is one. */
  			if (a->nam && domatch(a->nam, com, 0)) {
! 			    if (!v)
  				puts(a->text);
  			    else if (a->cmd)
  				printf((csh) ? "%s: aliased to %s\n" :
***************
*** 3337,3342 ****
--- 3335,3352 ----
  			}
  		    }
  		}
+ 		/* ... reserved words ... */
+ 		n = reswdtab->hsize;
+ 		for (i = 0; i < n; i++) {
+ 		    for (rw = (struct reswd *)reswdtab->nodes[i]; rw;
+ 			 rw = (struct reswd *)rw->next) {
+ 			if (rw->nam && domatch(rw->nam, com, 0))
+ 			    printf((csh) ? "%s: shell reserved word\n" :
+ 				   (v) ? "%s is a reserved word\n" : "%s\n",
+ 				   rw->nam);
+ 		    }
+ 		}
+ 		/* ... and builtins and shell functions. */
  		n = cmdnamtab->hsize;
  		for (i = 0; i < n; i++) {
  		    for (chn = (struct cmdnam *)cmdnamtab->nodes[i]; chn;
***************
*** 3389,3400 ****
  	} else {
  	    /* Not treating args as glob patterns. */
  	    informed = 0;
! 	    /* Look for reserved word or alias, unless -p was used. */
  	    if (!ops['p'] && (a = (Alias) gethnode(*argv, aliastab))) {
! 		if (a->cmd < 0)
! 		    printf((csh) ? "%s: shell reserved word\n" :
! 			   (v) ? "%s is a reserved word\n" : "%s\n", *argv);
! 		else if (!v)
  		    puts(a->text);
  		else if (a->cmd)
  		    printf((csh) ? "%s: aliased to %s\n" :
--- 3399,3407 ----
  	} else {
  	    /* Not treating args as glob patterns. */
  	    informed = 0;
! 	    /* Look for alias, unless -p was used. */
  	    if (!ops['p'] && (a = (Alias) gethnode(*argv, aliastab))) {
! 		if (!v)
  		    puts(a->text);
  		else if (a->cmd)
  		    printf((csh) ? "%s: aliased to %s\n" :
***************
*** 3406,3411 ****
--- 3413,3426 ----
  		    continue;
  		informed = 1;
  	    }
+ 	    /* Look for reserved word unless -p was used. */
+ 	    if (!ops['p'] && gethnode(*argv, reswdtab)) {
+ 		printf((csh) ? "%s: shell reserved word\n" :
+ 		       (v) ? "%s is a reserved word\n" : "%s\n", *argv);
+ 		if (!all)
+ 		    continue;
+ 		informed = 1;
+ 	    }
  	    /* Look for builtin or function, if -p was not used. */
  	    if (!ops['p'] && (chn = (Cmdnam) gethnode(*argv, cmdnamtab)) &&
  		(chn->flags & (SHFUNC | BUILTIN))) {
***************
*** 3895,3901 ****
  	    for (i = 0; i < n; i++) {
  		for (a = (Alias) aliastab->nodes[i]; a; a = dat) {
  		    dat = (Alias) a->next;
! 		    if (a->nam && a->cmd >= 0 && domatch(a->nam, com, 0))
  			freeanode(remhnode(a->nam, aliastab)), match++;
  		}
  	    }
--- 3910,3916 ----
  	    for (i = 0; i < n; i++) {
  		for (a = (Alias) aliastab->nodes[i]; a; a = dat) {
  		    dat = (Alias) a->next;
! 		    if (a->nam && domatch(a->nam, com, 0))
  			freeanode(remhnode(a->nam, aliastab)), match++;
  		}
  	    }
***************
*** 3903,3909 ****
  		ret = 1;
  	} else {
  	    /* remove the specified alias */
! 	    if ((dat = (Alias) gethnode(*argv++, aliastab)) && dat->cmd >= 0)
  		freeanode(remhnode(dat->nam, aliastab));
  	    else
  		ret = 1;
--- 3918,3924 ----
  		ret = 1;
  	} else {
  	    /* remove the specified alias */
! 	    if ((dat = (Alias) gethnode(*argv++, aliastab)))
  		freeanode(remhnode(dat->nam, aliastab));
  	    else
  		ret = 1;
***************
*** 3921,3929 ****
      char *ptr;
      int special = 0, inquote = 0;
  
!     if (a->cmd >= 0 && (!showflag ||		/* a single requested alias */
! 			(showflag == 1 && !a->cmd) ||	/* global alias */
! 			(showflag == 2 && a->cmd))) {	/* regular alias */
  	/* check for special characters in the expansion text */
  	for (ptr = a->text; *ptr; ptr++)
  	    if (ispecial(*ptr))
--- 3936,3944 ----
      char *ptr;
      int special = 0, inquote = 0;
  
!     if (!showflag ||			/* a single requested alias */
! 	(showflag == 1 && !a->cmd) ||   /* global alias */
! 	(showflag == 2 && a->cmd)) {	/* regular alias */
  	/* check for special characters in the expansion text */
  	for (ptr = a->text; *ptr; ptr++)
  	    if (ispecial(*ptr))
*** Src/globals.h.ali	Wed May 24 18:14:18 1995
--- Src/globals.h	Wed May 24 18:13:44 1995
***************
*** 250,259 ****
   
  EXTERN int prevjob;
   
! /* hash table containing the aliases and reserved words */
   
  EXTERN Hashtab aliastab;
   
  /* hash table containing the parameters */
   
  EXTERN Hashtab paramtab;
--- 250,263 ----
   
  EXTERN int prevjob;
   
! /* hash table containing the aliases */
   
  EXTERN Hashtab aliastab;
   
+ /* hash table containing the reserved words */
+ 
+ EXTERN Hashtab reswdtab;
+ 
  /* hash table containing the parameters */
   
  EXTERN Hashtab paramtab;
*** Src/init.c.ali	Wed May 24 18:19:11 1995
--- Src/init.c	Thu May 25 12:06:28 1995
***************
*** 666,671 ****
--- 666,672 ----
  void
  addreswords(void)
  {
+ /* add the reserved words to their hash table:  should only be called once. */
      static char *reswds[] =
      {
  	"do", "done", "esac", "then", "elif", "else", "fi", "for", "case",
***************
*** 674,681 ****
      };
      int t0;
  
!     for (t0 = 0; reswds[t0]; t0++)
! 	addhnode(ztrdup(reswds[t0]), mkanode(NULL, -1 - t0), aliastab, NULL);
  }
  
  /**/
--- 675,690 ----
      };
      int t0;
  
!     /* twenty four reserved words; any advance on the following? */
!     reswdtab = newhtable(23);
!     /* Add the actual words, not copies, to the table, as we do not
!      * expect to modify the table again.
!      */
!     for (t0 = 0; reswds[t0]; t0++) {
! 	struct reswd *ptr = (struct reswd *) zcalloc(sizeof *ptr);
! 	ptr->cmd = t0 + DO;
! 	addhnode(reswds[t0], ptr, reswdtab, NULL);
!     }
  }
  
  /**/
*** Src/lex.c.ali	Fri May 19 10:10:38 1995
--- Src/lex.c	Thu May 25 12:13:01 1995
***************
*** 919,924 ****
--- 919,925 ----
  exalias(void)
  {
      struct alias *an;
+     struct reswd *rw;
      char *s, *t;
  
      s = yytext = hwadd();
***************
*** 940,965 ****
  	    return 0;
  	}
      }
      an = noaliases ? NULL : (struct alias *)gethnode(s, aliastab);
!     if (t)
! 	*t = HISTSPACE;
!     if (alstackind != MAXAL && an && !an->inuse)
! 	if (!(an->cmd && !incmdpos && alstat != ALSTAT_MORE)) {
! 	    if (an->cmd < 0) {
! 		tok = DO - an->cmd - 1;
! 		return 0;
! 	    } else {
! 		an->inuse = 1;
! 		hungets(ALPOPS);
! 		hungets((alstack[alstackind++] = an)->text);
! 		alstat = 0;
  	    /* remove from history if it begins with space */
! 		if (isset(HISTIGNORESPACE) && an->text[0] == ' ')
! 		    remhist();
! 		lexstop = 0;
! 		return 1;
! 	    }
  	}
      return 0;
  }
  
--- 941,971 ----
  	    return 0;
  	}
      }
+ 
+     /* Check for an alias */
      an = noaliases ? NULL : (struct alias *)gethnode(s, aliastab);
!     if (alstackind != MAXAL && an && !an->inuse
! 	&& (!an->cmd || incmdpos || alstat == ALSTAT_MORE)) {
! 	    an->inuse = 1;
! 	    hungets(ALPOPS);
! 	    hungets((alstack[alstackind++] = an)->text);
! 	    alstat = 0;
  	    /* remove from history if it begins with space */
! 	    if (isset(HISTIGNORESPACE) && an->text[0] == ' ')
! 		remhist();
! 	    lexstop = 0;
! 	    if (t)
! 		*t = HISTSPACE;
! 	    return 1;
  	}
+ 
+     /* Then check for a reserved word (ignored if noaliases is set) */
+     rw = (noaliases || !incmdpos) ? NULL
+ 	: (struct reswd *)gethnode(s, reswdtab);
+     if (rw)
+ 	tok = rw->cmd;
+     if (t)
+ 	*t = HISTSPACE;
      return 0;
  }
  
*** Src/utils.c.ali	Tue May 23 14:20:31 1995
--- Src/utils.c	Thu May 25 10:35:43 1995
***************
*** 1145,1151 ****
  	return;
      if (!(*s)[0] || !(*s)[1])
  	return;
!     if (gethnode(*s, cmdnamtab) || gethnode(*s, aliastab))
  	return;
      else if (isset(HASHLISTALL)) {
  	fullhash();
--- 1151,1158 ----
  	return;
      if (!(*s)[0] || !(*s)[1])
  	return;
!     if (gethnode(*s, cmdnamtab) || gethnode(*s, aliastab)
! 	|| gethnode(*s, reswdtab))
  	return;
      else if (isset(HASHLISTALL)) {
  	fullhash();
***************
*** 1183,1188 ****
--- 1190,1196 ----
  		return;
  	    guess = *s;
  	    d = 100;
+ 	    listhtable(reswdtab, spscan);
  	    listhtable(aliastab, spscan);
  	    listhtable(cmdnamtab, spscan);
  	}
*** Src/zle_tricky.c.ali	Tue May 23 14:20:34 1995
--- Src/zle_tricky.c	Wed May 24 18:41:11 1995
***************
*** 2705,2710 ****
--- 2705,2711 ----
      if (!ic && (cc->mask & CC_COMMPATH) && !*ppre && !*psuf) {
  	/* If we have to complete commands, add alias names, too. */
  	dumphtable(aliastab, -2);
+ 	dumphtable(reswdtab, -2);
  	if (isset(HASHLISTALL))
  	    fullhash();
  	dumphtable(cmdnamtab, -3);

-- 
Peter Stephenson <P.Stephenson@swansea.ac.uk>  Tel: +44 1792 205678 extn. 4461
WWW:  http://python.swan.ac.uk/~pypeters/      Fax: +44 1792 295324
Department of Physics, University of Wales, Swansea,
Singleton Park, Swansea, SA2 8PP, U.K.


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Reserved words and aliases
  1995-05-25 13:05 Reserved words and aliases P.Stephenson
@ 1995-05-25 23:58 ` Richard Coleman
       [not found]   ` <coleman@math.gatech.edu>
  0 siblings, 1 reply; 4+ messages in thread
From: Richard Coleman @ 1995-05-25 23:58 UTC (permalink / raw)
  To: zsh-workers

> The problem is a Z-shell Kludge (TM):  the aliases and reserved words
> shared the same hash table.  The old behaviour was that making exec
> an alias stopped the real exec from being recognised as a shell
> reserved word and this couldn't be undone.
> 
> I could have fixed this by compounding the kludge, e.g. by adding an
> extra flag if an alias was a reserved word that was aliased.  Instead
> I decided to do it properly and put the reserved words in their own
> hash table.  This enabled some minor data size optimisations at the
> expense of some minor code increase.  It also opens the way in future
> to turn off aliases as an option if that ever becomes necessary.

Totally excellent!  I think there are some other tables that probably
should be split like this.

> There is the odd minor but reasonable change in behaviour, for example
> compctl's alias flag won't produce reserved words any more (they still
> appear for command completion and spell checking).

I guess we will need (yet another) flag to match reserved words.  I
consider that a small price to pay for this particular cleanup.

> You can now do
> 
> % alias exec="((SHLVL++, SAVEHIST=0)); exec"
> 
> if you really want.

I'm not sure why you would want to do this, but it's cool that
it will be possible.

rc


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Reserved words and aliases
       [not found]   ` <coleman@math.gatech.edu>
@ 1995-05-26  0:49     ` Barton E. Schaefer
  0 siblings, 0 replies; 4+ messages in thread
From: Barton E. Schaefer @ 1995-05-26  0:49 UTC (permalink / raw)
  To: zsh-workers

On May 25,  7:58pm, Richard Coleman wrote:
} Subject: Re: Reserved words and aliases
}
} > You can now do
} > 
} > % alias exec="((SHLVL++, SAVEHIST=0)); exec"
} > 
} > if you really want.
} 
} I'm not sure why you would want to do this

Do the words "compatibility with older versions of zsh" ring any bells?

-- 
Bart Schaefer                     Vice President, Technology, Z-Code Software
schaefer@z-code.com               Division of Network Computing Devices, Inc.
http://www.well.com/www/barts


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: reserved words and aliases
       [not found] <9505260442.AA02643@redwood.skiles.gatech.edu>
@ 1995-05-26  9:44 ` P.Stephenson
  0 siblings, 0 replies; 4+ messages in thread
From: P.Stephenson @ 1995-05-26  9:44 UTC (permalink / raw)
  To: Richard Coleman; +Cc: Zsh hackers list

coleman@math.gatech.edu wrote:
>   In your patch to split reserved words and aliases,
> you are missing the piece of the patch for zsh.h.  Your
> patch doesn't define "struct reswd" which is a slight
> problem of course :-)

oops --- yes, reswd is a reduced `struct alias' with just the token
number remaining.

*** Src/zsh.h~	Fri May 19 10:10:18 1995
--- Src/zsh.h	Thu May 25 12:13:29 1995
***************
*** 645,650 ****
--- 645,658 ----
      int inuse;			/* alias is being expanded                  */
  };
  
+ /* node in shell reserved word list */
+ 
+ struct reswd {
+     struct hashnode *next;
+     char *nam;			/* name of reserved word */
+     int cmd;			/* corresponding token */
+ };
+ 
  /* node in sched list */
  
  struct schedcmd {

-- 
Peter Stephenson <P.Stephenson@swansea.ac.uk>  Tel: +44 1792 205678 extn. 4461
WWW:  http://python.swan.ac.uk/~pypeters/      Fax: +44 1792 295324
Department of Physics, University of Wales, Swansea,
Singleton Park, Swansea, SA2 8PP, U.K.


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~1995-05-26  9:49 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1995-05-25 13:05 Reserved words and aliases P.Stephenson
1995-05-25 23:58 ` Richard Coleman
     [not found]   ` <coleman@math.gatech.edu>
1995-05-26  0:49     ` Barton E. Schaefer
     [not found] <9505260442.AA02643@redwood.skiles.gatech.edu>
1995-05-26  9:44 ` reserved " P.Stephenson

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).