From 241b072099602d72d174ec57d151f5f881949f8d Mon Sep 17 00:00:00 2001 From: tg Date: Mon, 1 May 2017 19:44:29 +0000 Subject: [PATCH] =?UTF-8?q?commit=20my=20WIP=20for=20the=20Beltane=20Snaps?= =?UTF-8?q?hot=20of=20the=20Mainframe=20Korn=20Shell,=20not=20going=20to?= =?UTF-8?q?=20make=20finishing=20it=20tonight=20=E2=98=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- check.t | 101 ++++++++++++++++++++++++++++++++++++++------------------ misc.c | 78 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 145 insertions(+), 34 deletions(-) diff --git a/check.t b/check.t index ed52588..2eb7831 100644 --- a/check.t +++ b/check.t @@ -1,4 +1,4 @@ -# $MirOS: src/bin/mksh/check.t,v 1.786 2017/04/29 21:49:04 tg Exp $ +# $MirOS: src/bin/mksh/check.t,v 1.787 2017/05/01 19:44:26 tg Exp $ # -*- mode: sh -*- #- # Copyright © 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, @@ -30,58 +30,62 @@ # (2013/12/02 20:39:44) http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/regress/bin/ksh/?sortby=date expected-stdout: - @(#)MIRBSD KSH R55 2017/04/27 + @(#)MIRBSD KSH R55 2017/05/01 description: - Check version of shell. + Check base version of full shell stdin: - echo $KSH_VERSION + echo ${KSH_VERSION%%' +'*} name: KSH_VERSION -category: !shell:legacy-yes,!shell:textmode-yes,!shell:ebcdic-yes +category: !shell:legacy-yes --- expected-stdout: - @(#)LEGACY KSH R55 2017/04/27 + @(#)LEGACY KSH R55 2017/05/01 description: - Check version of legacy shell. + Check base version of legacy shell stdin: - echo $KSH_VERSION + echo ${KSH_VERSION%%' +'*} name: KSH_VERSION-legacy -category: !shell:legacy-no,!shell:textmode-yes,!shell:ebcdic-yes +category: !shell:legacy-no --- -expected-stdout: - @(#)MIRBSD KSH R55 2017/04/27 +EBCDIC +name: KSH_VERSION-ascii description: - Check version of shell. + Check that the shell version tag does not include EBCDIC +category: !shell:ebcdic-yes stdin: - echo $KSH_VERSION + for x in $KSH_VERSION; do + [[ $x = '+EBCDIC' ]] && exit 1 + done + exit 0 +--- name: KSH_VERSION-ebcdic -category: !shell:legacy-yes,!shell:textmode-yes,!shell:ebcdic-no ---- -expected-stdout: - @(#)LEGACY KSH R55 2017/04/27 +EBCDIC description: - Check version of legacy shell. + Check that the shell version tag includes EBCDIC +category: !shell:ebcdic-no stdin: - echo $KSH_VERSION -name: KSH_VERSION-legacy-ebcdic -category: !shell:legacy-no,!shell:textmode-yes,!shell:ebcdic-no + for x in $KSH_VERSION; do + [[ $x = '+EBCDIC' ]] && exit 0 + done + exit 1 --- -expected-stdout: - @(#)MIRBSD KSH R55 2017/04/27 +TEXTMODE +name: KSH_VERSION-binmode description: - Check version of shell. + Check that the shell version tag does not include TEXTMODE +category: !shell:textmode-yes stdin: - echo $KSH_VERSION + for x in $KSH_VERSION; do + [[ $x = '+TEXTMODE' ]] && exit 1 + done + exit 0 +--- name: KSH_VERSION-textmode -category: !shell:legacy-yes,!shell:textmode-no ---- -expected-stdout: - @(#)LEGACY KSH R55 2017/04/27 +TEXTMODE description: - Check version of legacy shell. + Check that the shell version tag includes TEXTMODE +category: !shell:textmode-no stdin: - echo $KSH_VERSION -name: KSH_VERSION-legacy-textmode -category: !shell:legacy-no,!shell:textmode-no + for x in $KSH_VERSION; do + [[ $x = '+TEXTMODE' ]] && exit 0 + done + exit 1 --- name: selftest-1 description: @@ -2353,16 +2357,25 @@ expected-stdout: name: glob-bad-1 description: Check that [ matches itself if it's not a valid bracket expr + but does not prevent globbing, while backslash-escaping does file-setup: dir 755 "[x" file-setup: file 644 "[x/foo" stdin: echo [* echo *[x echo [x/* + :>'ab[x' + :>'a[a-z][x' + echo a[a-z][* + echo a[a-z]* + echo a[a\-z]* expected-stdout: [x [x [x/foo + ab[x + ab[x + a[a-z]* --- name: glob-bad-2 description: @@ -2470,11 +2483,33 @@ file-setup: file 644 "cbc" file-setup: file 644 "dbc" file-setup: file 644 "ebc" file-setup: file 644 "-bc" +file-setup: file 644 "@bc" stdin: echo [a-c-e]* + #XXX TODO: echo [a--@]* + # -> @bc expected-stdout: -bc abc bbc cbc ebc --- +name: glob-word-1 +description: + Check BSD word boundary matches +stdin: + t() { [[ $1 = *[[:\<:]]bar[[:\>:]]* ]]; echo =$?; } + t 'foo bar baz' + t 'foobar baz' + t 'foo barbaz' + t 'bar' + t '_bar' + t 'bar_' +expected-stdout: + =0 + =1 + =1 + =0 + =1 + =1 +--- name: glob-trim-1 description: Check against a regression from fixing IFS-subst-2 diff --git a/misc.c b/misc.c index 510af71..da3f0eb 100644 --- a/misc.c +++ b/misc.c @@ -32,7 +32,7 @@ #include #endif -__RCSID("$MirOS: src/bin/mksh/misc.c,v 1.273 2017/05/01 15:59:45 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/misc.c,v 1.274 2017/05/01 19:44:29 tg Exp $"); #define KSH_CHVT_FLAG #ifdef MKSH_SMALL @@ -917,8 +917,84 @@ do_gmatch(const unsigned char *s, const unsigned char *se, return (s == se); } +/*XXX this is a prime example for bsearch or a const hashtable */ +static const struct cclass { + const char *name; + uint32_t value; +} cclasses[] = { + /* POSIX */ + { "alnum", C_ALNUM }, + { "alpha", C_ALPHA }, + { "blank", C_BLANK }, + { "cntrl", C_CNTRL }, + { "digit", C_DIGIT }, + { "graph", C_GRAPH }, + { "lower", C_LOWER }, + { "print", C_PRINT }, + { "punct", C_PUNCT }, + { "space", C_SPACE }, + { "upper", C_UPPER }, + { "xdigit", C_SEDEC }, + /* BSD */ + /* "<" and ">" are handled inline */ + /* GNU bash */ + { "ascii", C_ASCII }, + { "word", C_ALNUX }, + /* mksh */ + { "sh_alias", C_ALIAS }, + { "sh_edq", C_EDQ }, + { "sh_ifs", C_IFS }, + { "sh_ifsws", C_IFSWS }, + { "sh_nl", C_NL }, + { "sh_quote", C_QUOTE }, + /* sentinel */ + { NULL, 0 } +}; + static const unsigned char * gmatch_cclass(const unsigned char *p, unsigned char sub) +#if 0 +gmatch_cclass(const unsigned char *pat, unsigned char sc) +{ + unsigned char c, subc; + const unsigned char *p = pat, *s; + bool found = false; + bool negated = false; + + /* check for negation */ + if (ISMAGIC(p[0]) && ord(p[1]) == ord('!')) { + p += 2; + negated = true; + } + /* make initial ] non-MAGIC */ + if (ISMAGIC(p[0]) && ord(p[1]) == ord(']')) + ++p; + /* iterate over bracket expression, debunk()ing on the fly */ + while ((c = *p++)) { + /* non-regular character? */ + if (ISMAGIC(c)) { + /* MAGIC + NUL cannot happen */ + if (!(c = *p++)) + break; + /* terminating bracket? */ + if (ord(c) == ord(']')) { + /* accept and return */ + return (found != negated ? p : NULL); + } + /* sub-bracket expressions */ + if (ord(c) == ord('[') && ( + /* collating element? */ + ord(*p) == ord('.') || + /* equivalence class? */ + ord(*p) == ord('=') || + /* character class? */ + ord(*p) == ord(':'))) { + /* must stop with exactly the same c */ + subc = *p++; + /* save away start of substring */ + s = p; +} +#endif { unsigned char c, d; bool notp, found = false;