From 1f9d2c7470f7d1a2a4310ad9541449a9f98b570f Mon Sep 17 00:00:00 2001 From: "Steffen (Daode) Nurpmeso" Date: Thu, 15 May 2014 15:13:57 +0200 Subject: [PATCH] Add `elif' command --- catd/en_US | 5 +++-- cc-test.sh | 36 +++++++++++++++++++++++++++++++++++- cmd3.c | 24 ++++++++++++++++++++++-- cmd_tab.h | 2 ++ nail.1 | 50 ++++++++++++++++++++++++++++++++++++++++---------- nailfuns.h | 3 ++- 6 files changed, 104 insertions(+), 16 deletions(-) diff --git a/catd/en_US b/catd/en_US index 62aff94d..f7ca50c6 100644 --- a/catd/en_US +++ b/catd/en_US @@ -44,9 +44,9 @@ $set 1 41 Non-null variable name required\n 42 `%s': the used selector is optional and not available\n 43 Unrecognized if-keyword: "%s"\n -44 "else" without matching "if"\n +44 `else' without matching `if'\n 45 The -H and -L options cannot be used in send mode.\n -46 "endif" without matching "if"\n +46 `endif' without matching `if'\n 47 No recipient specified. 48 No applicable messages. 49 Cannot call hook for folder "%s": Macro "%s" does not exist.\n @@ -584,3 +584,4 @@ $ It follows the "help command" one line help block, alpha-sorted (see nail.1) 577 notBefore = %s\n 578 notAfter = %s\n 579 ERROR +580 `elif' without matching `if'\n diff --git a/cc-test.sh b/cc-test.sh index 35d024d4..02731d23 100755 --- a/cc-test.sh +++ b/cc-test.sh @@ -219,8 +219,42 @@ __behave_ifelse() { endif echo 9.ok3 endif + # `elif' + if $dietcurd == 'yohu' + echo 10.err1 + elif $dietcurd == 'yoha' + echo 10.err2 + elif $dietcurd == 'yohe' + echo 10.err3 + elif $dietcurd == 'yoho' + echo 10.ok1 + if $dietcurd == 'yohu' + echo 10.err4 + elif $dietcurd == 'yoha' + echo 10.err5 + elif $dietcurd == 'yohe' + echo 10.err6 + elif $dietcurd == 'yoho' + echo 10.ok2 + if $dietcurd == 'yohu' + echo 10.err7 + elif $dietcurd == 'yoha' + echo 10.err8 + elif $dietcurd == 'yohe' + echo 10.err9 + elif $dietcurd == 'yoho' + echo 10.ok3 + else + echo 10.err10 + endif + else + echo 10.err11 + endif + else + echo 10.err12 + endif __EOT - cksum_test behave:if-normal "${MBOX}" '1909382116 98' + cksum_test behave:if-normal "${MBOX}" '2760114576 119' if have_feat REGEX; then ${rm} -f "${MBOX}" diff --git a/cmd3.c b/cmd3.c index 14a8d3f5..df1f296e 100644 --- a/cmd3.c +++ b/cmd3.c @@ -1156,6 +1156,26 @@ jleave: } FL int +c_elif(void *v) +{ + struct cond_stack *csp; + int rv; + NYD_ENTER; + + if ((csp = _cond_stack) == NULL || csp->c_else) { + fprintf(stderr, tr(580, "`elif' without matching `if'\n")); + rv = 1; + } else { + csp->c_go = !csp->c_go; + rv = c_if(v); + _cond_stack->c_outer = csp->c_outer; + free(csp); + } + NYD_LEAVE; + return rv; +} + +FL int c_else(void *v) { int rv; @@ -1163,7 +1183,7 @@ c_else(void *v) UNUSED(v); if (_cond_stack == NULL || _cond_stack->c_else) { - fprintf(stderr, tr(44, "\"else\" without matching \"if\"\n")); + fprintf(stderr, tr(44, "`else' without matching `if'\n")); rv = 1; } else { _cond_stack->c_go = !_cond_stack->c_go; @@ -1183,7 +1203,7 @@ c_endif(void *v) UNUSED(v); if ((csp = _cond_stack) == NULL) { - fprintf(stderr, tr(46, "\"endif\" without matching \"if\"\n")); + fprintf(stderr, tr(46, "`endif' without matching `if'\n")); rv = 1; } else { _cond_stack = csp->c_outer; diff --git a/cmd_tab.h b/cmd_tab.h index 39aaa616..4fa35c50 100644 --- a/cmd_tab.h +++ b/cmd_tab.h @@ -229,6 +229,8 @@ DS(327, "Part of the if .. then .. endif statement") }, { "else", &c_else, (F | M | RAWLIST), 0, 0 DS(327, "Part of the if .. then .. endif statement") }, + { "elif", &c_elif, (F | M | RAWLIST), 1, 3 + DS(327, "Part of the if .. then .. endif statement") }, { "endif", &c_endif, (F | M | RAWLIST), 0, 0 DS(327, "Part of the if .. then .. endif statement") }, { "alternates", &c_alternates, (M | RAWLIST), 0, 1000 diff --git a/nail.1 b/nail.1 index 2e77f9b3..1446fe80 100644 --- a/nail.1 +++ b/nail.1 @@ -1283,11 +1283,36 @@ The escape sequences `\ea', `\eb', `\ec', `\ef', `\en', `\er', `\et', Modified contents are discarded unless the .Va writebackedited variable is set. +.It Ic elif +Part of the +.Ic if / +.Ic elif / +.Ic else / +.Ic endif +conditional \(em if the condition of a preceeding +.Ic if +was false, check the following condition and execute the following block +if it evaluates true. .It Ic else -Marks the end of the then-part of an if statement and the beginning of -the part to take effect if the condition of the if statement is false. +Part of the +.Ic if / +.Ic elif / +.Ic else / +.Ic endif +conditional \(em if none of the conditions of the preceeding +.Ic if +and +.Ic elif +commands was true, the +.Ic else +block is executed. .It Ic endif -Marks the end of an if statement. +Marks the end of an +.Ic if / +.Ic elif / +.Ic else / +.Ic endif +conditional execution block. .It Ic exit (ex or x) Effects an immediate return to the Shell without modifying the user's system mailbox, his `mbox' file, or his edit file in @@ -1505,8 +1530,13 @@ command issued after .Ic hold will display the following message, not the current one. .It Ic if -Commands in \*(UA's startup files can be executed conditionally by -testing conditions via the nestable command `if', as in: +Part of the nestable +.Ic if / +.Ic elif / +.Ic else / +.Ic endif +conditional execution construct \(em if the given condition is false +execute the following block. .Bd -literal -offset indent if receive commands ... @@ -1515,10 +1545,10 @@ testing conditions via the nestable command `if', as in: endif .Ed .Pp -Note that the only allowed conditions are `[Rr]eceive', `[Ss]end', -`[Tt]erm' (execute if standard input is a tty), as well as `0' (never -execute) and `1' (always execute). -In addition it is possible to conditionalize upon wether an option is set, +Note that POSIX only supports the conditions `[Rr]eceive', `[Ss]end' +and `[Tt]erm' (execute if standard input is a tty). +Extensions are `0' (never execute) and `1' (always execute); +it is also possible to conditionalize upon wether an option is set, or set to a specific value, by using the `$' conditional trigger, e.g.: .Bd -literal -offset indent if $debug @@ -1536,7 +1566,7 @@ The first form simply checks wether an option is set, the other two also perform value content comparison (equality and non-equality, respectively); an unset value is treated as the empty string, then. The \*(OPal regular expression support adds `=~' and `!~' tests, which -treat the right hand side as a regular expression instead (see +treat the right hand side as a regular expression, e.g., `^UTF.*' (see .Xr re_format 7 Ns ). .It Ic ignore diff --git a/nailfuns.h b/nailfuns.h index 31f16ce7..893a74ca 100644 --- a/nailfuns.h +++ b/nailfuns.h @@ -605,13 +605,14 @@ FL int c_file(void *v); /* Expand file names like echo */ FL int c_echo(void *v); -/* if.else.endif conditional execution. +/* if.elif.else.endif conditional execution. * condstack_isskip() returns wether the current condition state doesn't allow * execution of commands. * condstack_release() and condstack_take() are used when sourcing files, they * rotate the current condition stack; condstack_take() returns a false boolean * if the current condition stack has unclosed conditionals */ FL int c_if(void *v); +FL int c_elif(void *v); FL int c_else(void *v); FL int c_endif(void *v); FL bool_t condstack_isskip(void); -- 2.11.4.GIT