zsh-workers
 help / color / mirror / code / Atom feed
* case fall-through
@ 1997-04-01  0:12 Zefram
  0 siblings, 0 replies; only message in thread
From: Zefram @ 1997-04-01  0:12 UTC (permalink / raw)
  To: zsh-workers

-----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-----


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~1997-04-01  0:25 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1997-04-01  0:12 case fall-through Zefram

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).