zsh-workers
 help / color / mirror / code / Atom feed
From: Zefram <zefram@dcs.warwick.ac.uk>
To: zsh-workers@math.gatech.edu
Subject: case fall-through
Date: Tue, 1 Apr 1997 01:12:48 +0100 (BST)	[thread overview]
Message-ID: <17975.199704010012@stone.dcs.warwick.ac.uk> (raw)

-----BEGIN PGP SIGNED MESSAGE-----

This patch adds a feature from (IIRC) ksh93.  There is a new token,
`;&', which behaves like `;;' except that it allows execution to fall
through to the next branch of the case.

The gettext code for case commands was actually completely broken
before this patch.  It stopped working between 3.0.2 and 3.0.3-test1
(and between 3.1.0-test3 and 3.1.0).  The 3.0 tree ought to have the
text.c hunks of this patch applied, minus the (fairly obvious) parts
relating to this new feature.

 -zefram

 *** Doc/Zsh/grammar.yo	1997/01/29 03:24:53	1.4
 --- Doc/Zsh/grammar.yo	1997/03/31 20:17:35
 ***************
 *** 146,156 ****
   findex(case)
   cindex(case selection)
   cindex(selection, case)
 ! item(tt(case) var(word) tt(in) [ [tt(LPAR())] var(pattern) [ tt(|) var(pattern) ] ... tt(RPAR()) var(list) tt(;;) ] ... tt(esac))(
   Execute the var(list) associated with the first var(pattern)
   that matches var(word), if any.  The form of the patterns
   is the same as that used for filename generation.  See
   noderef(Filename Generation).
   )
   findex(select)
   cindex(user selection)
 --- 146,159 ----
   findex(case)
   cindex(case selection)
   cindex(selection, case)
 ! item(tt(case) var(word) tt(in) [ [tt(LPAR())] var(pattern) [ tt(|) var(pattern) ] ... tt(RPAR()) var(list) (tt(;;)|tt(;&)) ] ... tt(esac))(
   Execute the var(list) associated with the first var(pattern)
   that matches var(word), if any.  The form of the patterns
   is the same as that used for filename generation.  See
   noderef(Filename Generation).
 + If the var(list) that is executed is terminated with tt(;&) rather than
 + tt(;;), the following list is also executed.  This continues until either
 + a list is terminated with tt(;;) or the tt(esac) is reached.
   )
   findex(select)
   cindex(user selection)
 ***************
 *** 243,249 ****
   item(tt(repeat) var(word) var(sublist))(
   This is a short form of tt(repeat).
   )
 ! item(tt(case) var(word) tt({) [ [tt(LPAR())] var(pattern) [ tt(|) var(pattern) ] ... tt(RPAR()) var(list) tt(;;) ] ... tt(}))(
   An alternative form of tt(case).
   )
   item(tt(select) var(name) [ tt(in) var(word) var(term) ] var(sublist))(
 --- 246,252 ----
   item(tt(repeat) var(word) var(sublist))(
   This is a short form of tt(repeat).
   )
 ! item(tt(case) var(word) tt({) [ [tt(LPAR())] var(pattern) [ tt(|) var(pattern) ] ... tt(RPAR()) var(list) (tt(;;)|tt(;&)) ] ... tt(}))(
   An alternative form of tt(case).
   )
   item(tt(select) var(name) [ tt(in) var(word) var(term) ] var(sublist))(
 *** Src/globals.h	1997/03/31 00:52:39	1.43
 --- Src/globals.h	1997/03/31 18:59:05
 ***************
 *** 694,699 ****
 --- 694,700 ----
       "((",	/* DINPAR	     */
       "))",	/* DOUTPAR	     */
       "&|",	/* AMPERBANG	  30 */
 +     ";&",	/* SEMIAMP	     */
   };
   #else
   extern char *tokstrings[];
 *** Src/lex.c	1997/02/04 14:13:05	1.27
 --- Src/lex.c	1997/03/31 19:05:14
 ***************
 *** 215,220 ****
 --- 215,221 ----
       case NEWLIN:
       case SEMI:
       case DSEMI:
 +     case SEMIAMP:
       case AMPER:
       case AMPERBANG:
       case INPAR:
 ***************
 *** 436,447 ****
   	return NEWLIN;
       case LX1_SEMI:
   	d = hgetc();
 ! 	if (d != ';') {
 ! 	    hungetc(d);
 ! 	    lexstop = 0;
 ! 	    return SEMI;
 ! 	}
 ! 	return DSEMI;
       case LX1_AMPER:
   	d = hgetc();
   	if (d == '&')
 --- 437,449 ----
   	return NEWLIN;
       case LX1_SEMI:
   	d = hgetc();
 ! 	if(d == ';')
 ! 	    return DSEMI;
 ! 	else if(d == '&')
 ! 	    return SEMIAMP;
 ! 	hungetc(d);
 ! 	lexstop = 0;
 ! 	return SEMI;
       case LX1_AMPER:
   	d = hgetc();
   	if (d == '&')
 *** Src/loop.c	1997/03/26 09:09:23	1.12
 --- Src/loop.c	1997/03/31 19:55:55
 ***************
 *** 387,400 ****
   
       if (node) {
   	while (*p) {
 ! 	    singsub(p);
 ! 	    if (matchpat(word, *p))
   		break;
   	    p++;
   	    l++;
   	}
 - 	if (*l)
 - 	    execlist(*l, 1, cmd->flags & CFLAG_EXEC);
       }
       return lastval;
   }
 --- 387,403 ----
   
       if (node) {
   	while (*p) {
 ! 	    char *pat = *p + 1;
 ! 	    singsub(&pat);
 ! 	    if (matchpat(word, pat)) {
 ! 		do {
 ! 		    execlist(*l++, 1, **p == ';' && (cmd->flags & CFLAG_EXEC));
 ! 		} while(**p++ == '&' && *p);
   		break;
 + 	    }
   	    p++;
   	    l++;
   	}
       }
       return lastval;
   }
 *** Src/parse.c	1997/01/29 03:25:22	1.18
 --- Src/parse.c	1997/03/31 19:15:33
 ***************
 *** 472,478 ****
   
   /*
    * case	: CASE STRING { SEPER } ( "in" | INBRACE )
 ! 				{ { SEPER } STRING { BAR STRING } OUTPAR list [ DSEMI ] }
   				{ SEPER } ( "esac" | OUTBRACE )
    */
   
 --- 472,479 ----
   
   /*
    * case	: CASE STRING { SEPER } ( "in" | INBRACE )
 ! 				{ { SEPER } STRING { BAR STRING } OUTPAR
 ! 					list [ DSEMI | SEMIAMP ] }
   				{ SEPER } ( "esac" | OUTBRACE )
    */
   
 ***************
 *** 522,528 ****
   	    yylex();
   	    break;
   	}
 ! 	str = tokstr;
   	incasepat = 0;
   	incmdpos = 1;
   	for (;;) {
 --- 523,531 ----
   	    yylex();
   	    break;
   	}
 ! 	str = ncalloc(strlen(tokstr) + 2);
 ! 	*str = ';';
 ! 	strcpy(str + 1, tokstr);
   	incasepat = 0;
   	incmdpos = 1;
   	for (;;) {
 ***************
 *** 549,557 ****
   		if (str[sl - 1] != Bar) {
   		    /* POSIX allows (foo*) patterns */
   		    int pct;
 ! 		    char *s = str;
   
 ! 		    for (s = str, pct = 0; *s; s++) {
   			if (*s == Inpar)
   			    pct++;
   			if (!pct)
 --- 552,560 ----
   		if (str[sl - 1] != Bar) {
   		    /* POSIX allows (foo*) patterns */
   		    int pct;
 ! 		    char *s;
   
 ! 		    for (s = str + 1, pct = 0; *s; s++) {
   			if (*s == Inpar)
   			    pct++;
   			if (!pct)
 ***************
 *** 568,574 ****
   			if (*s == Outpar)
   			    pct--;
   		    }
 ! 		    if (*s || pct || s == str)
   			YYERRORV;
   		    break;
   		} else {
 --- 571,577 ----
   			if (*s == Outpar)
   			    pct--;
   		    }
 ! 		    if (*s || pct || s == str + 1)
   			YYERRORV;
   		    break;
   		} else {
 ***************
 *** 590,596 ****
   	    yylex();
   	    break;
   	}
 ! 	if (tok != DSEMI)
   	    YYERRORV;
   	incasepat = 1;
   	incmdpos = 0;
 --- 593,601 ----
   	    yylex();
   	    break;
   	}
 ! 	if(tok == SEMIAMP)
 ! 	    *str = '&';
 ! 	else if (tok != DSEMI)
   	    YYERRORV;
   	incasepat = 1;
   	incmdpos = 0;
 *** Src/text.c	1997/01/29 03:25:27	1.11
 --- Src/text.c	1997/03/31 20:01:13
 ***************
 *** 264,281 ****
   	    taddstr("fi");
   	    break;
   	case CCASE:
 - 	    taddstr("case ");
 - 	    taddlist(nn->args);
 - 	    taddstr(" in");
 - 	    tindent++;
 - 	    taddnl();
   	    gt2(nn->u.casecmd);
 - 	    tindent--;
 - 	    if (tnewlins)
 - 		taddnl();
 - 	    else
 - 		taddchr(' ');
 - 	    taddstr("esac");
   	    break;
   	case COND:
   	    taddstr("[[ ");
 --- 264,270 ----
 ***************
 *** 316,333 ****
   	    l = _casecmd(n)->lists;
   	    p = _casecmd(n)->pats;
   
   	    for (; *l; p++, l++) {
 - 		taddstr(*p);
 - 		taddstr(") ");
 - 		tindent++;
 - 		gt2(*l);
 - 		tindent--;
 - 		taddstr(";;");
   		if (tnewlins)
   		    taddnl();
   		else
   		    taddchr(' ');
   	    }
   	    break;
   	}
       case N_IF:
 --- 305,333 ----
   	    l = _casecmd(n)->lists;
   	    p = _casecmd(n)->pats;
   
 + 	    taddstr("case ");
 + 	    taddstr(*p++);
 + 	    taddstr(" in");
 + 	    tindent++;
   	    for (; *l; p++, l++) {
   		if (tnewlins)
   		    taddnl();
   		else
   		    taddchr(' ');
 + 		taddstr(*p + 1);
 + 		taddstr(") ");
 + 		tindent++;
 + 		gt2(*l);
 + 		tindent--;
 + 		taddstr(" ;");
 + 		taddchr(**p);
   	    }
 + 	    tindent--;
 + 	    if (tnewlins)
 + 		taddnl();
 + 	    else
 + 		taddchr(' ');
 + 	    taddstr("esac");
   	    break;
   	}
       case N_IF:
 *** Src/zsh.h	1997/03/31 07:51:13	1.56
 --- Src/zsh.h	1997/03/31 19:01:56
 ***************
 *** 116,122 ****
   
   #define SPECCHARS "#$^*()=|{}[]`<>?~;&\n\t \\\'\""
   
 ! enum shopt {
       NULLTOK,		/* 0  */
       SEPER,
       NEWLIN,
 --- 116,122 ----
   
   #define SPECCHARS "#$^*()=|{}[]`<>?~;&\n\t \\\'\""
   
 ! enum {
       NULLTOK,		/* 0  */
       SEPER,
       NEWLIN,
 ***************
 *** 148,185 ****
       DINPAR,
       DOUTPAR,
       AMPERBANG,		/* 30 */
       DOUTBRACK,
       STRING,
       ENVSTRING,
 !     ENVARRAY,
 !     ENDINPUT,		/* 35 */
       LEXERR,
   
       /* Tokens for reserved words */
       BANG,	/* !         */
       DINBRACK,	/* [[        */
 !     INBRACE,    /* {         */
 !     OUTBRACE,   /* }         */	/* 40 */
       CASE,	/* case      */
       COPROC,	/* coproc    */
       DO,		/* do        */
 !     DONE,	/* done      */
 !     ELIF,	/* elif      */ /* 45 */
       ELSE,	/* else      */
       ZEND,	/* end       */
       ESAC,	/* esac      */
 !     FI,		/* fi        */
 !     FOR,	/* for       */ /* 50 */
       FOREACH,	/* foreach   */
       FUNC,	/* function  */
       IF,		/* if        */
 !     NOCORRECT,	/* nocorrect */
 !     REPEAT,	/* repeat    */ /* 55 */
       SELECT,	/* select    */
       THEN,	/* then      */
       TIME,	/* time      */
 !     UNTIL,	/* until     */
 !     WHILE	/* while     */ /* 60 */
   };
   
   /* Redirection types.  If you modify this, you may also have to modify *
 --- 148,186 ----
       DINPAR,
       DOUTPAR,
       AMPERBANG,		/* 30 */
 +     SEMIAMP,
       DOUTBRACK,
       STRING,
       ENVSTRING,
 !     ENVARRAY,		/* 35 */
 !     ENDINPUT,
       LEXERR,
   
       /* Tokens for reserved words */
       BANG,	/* !         */
       DINBRACK,	/* [[        */
 !     INBRACE,    /* {         */	/* 40 */
 !     OUTBRACE,   /* }         */
       CASE,	/* case      */
       COPROC,	/* coproc    */
       DO,		/* do        */
 !     DONE,	/* done      */ /* 45 */
 !     ELIF,	/* elif      */
       ELSE,	/* else      */
       ZEND,	/* end       */
       ESAC,	/* esac      */
 !     FI,		/* fi        */ /* 50 */
 !     FOR,	/* for       */
       FOREACH,	/* foreach   */
       FUNC,	/* function  */
       IF,		/* if        */
 !     NOCORRECT,	/* nocorrect */ /* 55 */
 !     REPEAT,	/* repeat    */
       SELECT,	/* select    */
       THEN,	/* then      */
       TIME,	/* time      */
 !     UNTIL,	/* until     */ /* 60 */
 !     WHILE	/* while     */
   };
   
   /* Redirection types.  If you modify this, you may also have to modify *

-----BEGIN PGP SIGNATURE-----
Version: 2.6.3ia
Charset: ascii

iQCVAwUBM0AeeHD/+HJTpU/hAQFXhAQAivqrVvHuhTndExTzOAqiA6+ghvI6Owkl
kMKRYrQ4UoftuNmSJ1UlUfs6lFUKNMNbxXD9ejm3po0PUVZFRPx+pu83DeWUBD2b
pJcnV6Fd+h+ikhPAmqi2+USK6c1dXMtbMEKeJm0Gvh6PJimV6FLqXFK9iuczNA5H
zxtntojvDiM=
=LsIz
-----END PGP SIGNATURE-----


                 reply	other threads:[~1997-04-01  0:25 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=17975.199704010012@stone.dcs.warwick.ac.uk \
    --to=zefram@dcs.warwick.ac.uk \
    --cc=zsh-workers@math.gatech.edu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).