From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from gatech.edu (gatech.edu [130.207.244.244]) by werple.mira.net.au (8.6.10/8.6.9) with SMTP id XAA05809 for ; Thu, 25 May 1995 23:10:41 +1000 Received: from math (math.skiles.gatech.edu) by gatech.edu with SMTP id AA06859 (5.65c/Gatech-10.0-IDA for ); Thu, 25 May 1995 09:09:42 -0400 Received: by math (5.x/SMI-SVR4) id AA23556; Thu, 25 May 1995 09:07:28 -0400 Resent-Date: Thu, 25 May 95 14:05:30 +0100 Old-Return-Path: Message-Id: <553.9505251305@pyro.swan.ac.uk> To: zsh-workers@math.gatech.edu (Zsh hackers list) Subject: Reserved words and aliases Date: Thu, 25 May 95 14:05:30 +0100 From: P.Stephenson@swansea.ac.uk X-Mts: smtp Resent-Message-Id: <"dO23O2.0.-l5.F48nl"@math> Resent-From: zsh-workers@math.gatech.edu X-Mailing-List: archive/latest/33 X-Loop: zsh-workers@math.gatech.edu Precedence: list Resent-Sender: zsh-workers-request@math.gatech.edu 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 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.