Upgrade to mksh R56c.
R56c is a bugfix-only release everyone must upgrade to: [komh] Remove redundant OS/2-specific code, clean up others [komh, tg] Fix drive-qualified (absolute and relative) DOS-style path support in realpath functionality, partially other places [tg] Don’t substitute ${ENV:-~/.mkshrc} result again [tg] Improve OS/2 $PATH (et al.) handling, drive-relative paths [tg] Add MKSH_ENVDIR compile-time option for Jehanne and Plan 9 [tg] Limit nesting when parsing malformed code (Debian #878947) [tg] Update wcwidth data with bugfixed script (still Unicode 10; resulting values are identical to glibc git master for extant chars) [Dr. Werner Fink] Raise some time limits in the testsuite [Shamar] Add support for the Jehanne operating system [komh] Set stdin to text mode before executing child processes on OS/2 [komh] Pass arguments via a resonse file if executing a child fails [Dr. Werner Fink] Early locale tracking as a compile-time option [tg] Fix regressions introduced with new fast character classes Bug: N/A Test: builds and boots Change-Id: I44da7a8bb9859a0357bcd59891dd4f2cfc199733
This commit is contained in:
parent
ab3794bf03
commit
dd4abe0a6a
19 changed files with 939 additions and 643 deletions
|
@ -108,7 +108,7 @@ cc_defaults {
|
||||||
"-DHAVE_SYS_ERRLIST_DECL=0",
|
"-DHAVE_SYS_ERRLIST_DECL=0",
|
||||||
"-DHAVE_SYS_SIGLIST_DECL=1",
|
"-DHAVE_SYS_SIGLIST_DECL=1",
|
||||||
"-DHAVE_PERSISTENT_HISTORY=0",
|
"-DHAVE_PERSISTENT_HISTORY=0",
|
||||||
"-DMKSH_BUILD_R=562",
|
"-DMKSH_BUILD_R=563",
|
||||||
|
|
||||||
// Additional flags
|
// Additional flags
|
||||||
"-DMKSH_DEFAULT_PROFILEDIR=\"/system/etc\"",
|
"-DMKSH_DEFAULT_PROFILEDIR=\"/system/etc\"",
|
||||||
|
|
23
src/Build.sh
Normal file → Executable file
23
src/Build.sh
Normal file → Executable file
|
@ -1,5 +1,5 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
srcversion='$MirOS: src/bin/mksh/Build.sh,v 1.727 2017/08/29 13:38:28 tg Exp $'
|
srcversion='$MirOS: src/bin/mksh/Build.sh,v 1.731 2018/01/13 21:38:06 tg Exp $'
|
||||||
#-
|
#-
|
||||||
# Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
|
# Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
|
||||||
# 2011, 2012, 2013, 2014, 2015, 2016, 2017
|
# 2011, 2012, 2013, 2014, 2015, 2016, 2017
|
||||||
|
@ -796,6 +796,8 @@ Harvey)
|
||||||
add_cppflags -DMKSH_ASSUME_UTF8
|
add_cppflags -DMKSH_ASSUME_UTF8
|
||||||
HAVE_ISSET_MKSH_ASSUME_UTF8=1
|
HAVE_ISSET_MKSH_ASSUME_UTF8=1
|
||||||
HAVE_ISOFF_MKSH_ASSUME_UTF8=0
|
HAVE_ISOFF_MKSH_ASSUME_UTF8=0
|
||||||
|
add_cppflags -DMKSH__NO_SYMLINK
|
||||||
|
check_categories="$check_categories nosymlink"
|
||||||
add_cppflags -DMKSH_NO_CMDLINE_EDITING
|
add_cppflags -DMKSH_NO_CMDLINE_EDITING
|
||||||
add_cppflags -DMKSH__NO_SETEUGID
|
add_cppflags -DMKSH__NO_SETEUGID
|
||||||
oswarn=' and will currently not work'
|
oswarn=' and will currently not work'
|
||||||
|
@ -819,6 +821,20 @@ Interix)
|
||||||
IRIX*)
|
IRIX*)
|
||||||
: "${HAVE_SETLOCALE_CTYPE=0}"
|
: "${HAVE_SETLOCALE_CTYPE=0}"
|
||||||
;;
|
;;
|
||||||
|
Jehanne)
|
||||||
|
add_cppflags -DMKSH_ASSUME_UTF8
|
||||||
|
HAVE_ISSET_MKSH_ASSUME_UTF8=1
|
||||||
|
HAVE_ISOFF_MKSH_ASSUME_UTF8=0
|
||||||
|
add_cppflags -DMKSH__NO_SYMLINK
|
||||||
|
check_categories="$check_categories nosymlink"
|
||||||
|
add_cppflags -DMKSH_NO_CMDLINE_EDITING
|
||||||
|
add_cppflags -DMKSH_DISABLE_REVOKE_WARNING
|
||||||
|
add_cppflags '-D_PATH_DEFPATH=\"/cmd\"'
|
||||||
|
add_cppflags '-DMKSH_DEFAULT_EXECSHELL=\"/cmd/mksh\"'
|
||||||
|
add_cppflags '-DMKSH_DEFAULT_PROFILEDIR=\"/cfg/mksh\"'
|
||||||
|
add_cppflags '-DMKSH_ENVDIR=\"/env\"'
|
||||||
|
SRCS="$SRCS jehanne.c"
|
||||||
|
;;
|
||||||
Linux)
|
Linux)
|
||||||
case $CC in
|
case $CC in
|
||||||
*tendracc*) ;;
|
*tendracc*) ;;
|
||||||
|
@ -947,6 +963,8 @@ Plan9)
|
||||||
add_cppflags -DMKSH_ASSUME_UTF8
|
add_cppflags -DMKSH_ASSUME_UTF8
|
||||||
HAVE_ISSET_MKSH_ASSUME_UTF8=1
|
HAVE_ISSET_MKSH_ASSUME_UTF8=1
|
||||||
HAVE_ISOFF_MKSH_ASSUME_UTF8=0
|
HAVE_ISOFF_MKSH_ASSUME_UTF8=0
|
||||||
|
add_cppflags -DMKSH__NO_SYMLINK
|
||||||
|
check_categories="$check_categories nosymlink"
|
||||||
add_cppflags -DMKSH_NO_CMDLINE_EDITING
|
add_cppflags -DMKSH_NO_CMDLINE_EDITING
|
||||||
add_cppflags -DMKSH__NO_SETEUGID
|
add_cppflags -DMKSH__NO_SETEUGID
|
||||||
oswarn=' and will currently not work'
|
oswarn=' and will currently not work'
|
||||||
|
@ -2409,7 +2427,7 @@ addsrcs '!' HAVE_STRLCPY strlcpy.c
|
||||||
addsrcs USE_PRINTF_BUILTIN printf.c
|
addsrcs USE_PRINTF_BUILTIN printf.c
|
||||||
test 1 = "$USE_PRINTF_BUILTIN" && add_cppflags -DMKSH_PRINTF_BUILTIN
|
test 1 = "$USE_PRINTF_BUILTIN" && add_cppflags -DMKSH_PRINTF_BUILTIN
|
||||||
test 1 = "$HAVE_CAN_VERB" && CFLAGS="$CFLAGS -verbose"
|
test 1 = "$HAVE_CAN_VERB" && CFLAGS="$CFLAGS -verbose"
|
||||||
add_cppflags -DMKSH_BUILD_R=562
|
add_cppflags -DMKSH_BUILD_R=563
|
||||||
|
|
||||||
$e $bi$me: Finished configuration testing, now producing output.$ao
|
$e $bi$me: Finished configuration testing, now producing output.$ao
|
||||||
|
|
||||||
|
@ -2733,6 +2751,7 @@ MKSH_DISABLE_DEPRECATED disable code paths scheduled for later removal
|
||||||
MKSH_DISABLE_EXPERIMENTAL disable code not yet comfy for (LTS) snapshots
|
MKSH_DISABLE_EXPERIMENTAL disable code not yet comfy for (LTS) snapshots
|
||||||
MKSH_DISABLE_TTY_WARNING shut up warning about ctty if OS cant be fixed
|
MKSH_DISABLE_TTY_WARNING shut up warning about ctty if OS cant be fixed
|
||||||
MKSH_DONT_EMIT_IDSTRING omit RCS IDs from binary
|
MKSH_DONT_EMIT_IDSTRING omit RCS IDs from binary
|
||||||
|
MKSH_EARLY_LOCALE_TRACKING track utf8-mode from POSIX locale, for SuSE
|
||||||
MKSH_MIDNIGHTBSD01ASH_COMPAT set -o sh: additional compatibility quirk
|
MKSH_MIDNIGHTBSD01ASH_COMPAT set -o sh: additional compatibility quirk
|
||||||
MKSH_NOPROSPECTOFWORK disable jobs, co-processes, etc. (do not use)
|
MKSH_NOPROSPECTOFWORK disable jobs, co-processes, etc. (do not use)
|
||||||
MKSH_NOPWNAM skip PAM calls, for -static on glibc or Solaris
|
MKSH_NOPWNAM skip PAM calls, for -static on glibc or Solaris
|
||||||
|
|
21
src/check.t
21
src/check.t
|
@ -1,4 +1,4 @@
|
||||||
# $MirOS: src/bin/mksh/check.t,v 1.797 2017/08/29 13:38:29 tg Exp $
|
# $MirOS: src/bin/mksh/check.t,v 1.801 2018/01/14 01:47:33 tg Exp $
|
||||||
# -*- mode: sh -*-
|
# -*- mode: sh -*-
|
||||||
#-
|
#-
|
||||||
# Copyright © 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
|
# Copyright © 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
|
||||||
|
@ -30,7 +30,7 @@
|
||||||
# (2013/12/02 20:39:44) http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/regress/bin/ksh/?sortby=date
|
# (2013/12/02 20:39:44) http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/regress/bin/ksh/?sortby=date
|
||||||
|
|
||||||
expected-stdout:
|
expected-stdout:
|
||||||
@(#)MIRBSD KSH R56 2017/08/29
|
@(#)MIRBSD KSH R56 2018/01/14
|
||||||
description:
|
description:
|
||||||
Check base version of full shell
|
Check base version of full shell
|
||||||
stdin:
|
stdin:
|
||||||
|
@ -39,7 +39,7 @@ name: KSH_VERSION
|
||||||
category: !shell:legacy-yes
|
category: !shell:legacy-yes
|
||||||
---
|
---
|
||||||
expected-stdout:
|
expected-stdout:
|
||||||
@(#)LEGACY KSH R56 2017/08/29
|
@(#)LEGACY KSH R56 2018/01/14
|
||||||
description:
|
description:
|
||||||
Check base version of legacy shell
|
Check base version of legacy shell
|
||||||
stdin:
|
stdin:
|
||||||
|
@ -3328,7 +3328,7 @@ stdin:
|
||||||
echo B
|
echo B
|
||||||
) &
|
) &
|
||||||
' &
|
' &
|
||||||
sleep 2
|
sleep 5
|
||||||
echo Left overs: *
|
echo Left overs: *
|
||||||
expected-stdout:
|
expected-stdout:
|
||||||
A
|
A
|
||||||
|
@ -3392,7 +3392,7 @@ stdin:
|
||||||
(sleep 1; foo) &
|
(sleep 1; foo) &
|
||||||
foo
|
foo
|
||||||
' &
|
' &
|
||||||
sleep 2
|
sleep 5
|
||||||
echo Left overs: *
|
echo Left overs: *
|
||||||
expected-stdout:
|
expected-stdout:
|
||||||
hi
|
hi
|
||||||
|
@ -6702,7 +6702,7 @@ name: regression-65
|
||||||
description:
|
description:
|
||||||
check for a regression with sleep builtin and signal mask
|
check for a regression with sleep builtin and signal mask
|
||||||
category: !nojsig
|
category: !nojsig
|
||||||
time-limit: 3
|
time-limit: 5
|
||||||
stdin:
|
stdin:
|
||||||
sleep 1
|
sleep 1
|
||||||
echo blub |&
|
echo blub |&
|
||||||
|
@ -9026,6 +9026,15 @@ expected-stdout:
|
||||||
.c:a b.c d..:
|
.c:a b.c d..:
|
||||||
.d:a b.c d..:
|
.d:a b.c d..:
|
||||||
---
|
---
|
||||||
|
name: arrassign-eol
|
||||||
|
description:
|
||||||
|
Commands after array assignments are not permitted
|
||||||
|
stdin:
|
||||||
|
foo=(a b) env
|
||||||
|
expected-exit: e != 0
|
||||||
|
expected-stderr-pattern:
|
||||||
|
/syntax error: unexpected 'env'/
|
||||||
|
---
|
||||||
name: arrassign-fnc-none
|
name: arrassign-fnc-none
|
||||||
description:
|
description:
|
||||||
Check locality of array access inside a function
|
Check locality of array access inside a function
|
||||||
|
|
160
src/edit.c
160
src/edit.c
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
|
* Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
|
||||||
* 2011, 2012, 2013, 2014, 2015, 2016, 2017
|
* 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018
|
||||||
* mirabilos <m@mirbsd.org>
|
* mirabilos <m@mirbsd.org>
|
||||||
*
|
*
|
||||||
* Provided that these terms and disclaimer and all copyright notices
|
* Provided that these terms and disclaimer and all copyright notices
|
||||||
|
@ -28,7 +28,7 @@
|
||||||
|
|
||||||
#ifndef MKSH_NO_CMDLINE_EDITING
|
#ifndef MKSH_NO_CMDLINE_EDITING
|
||||||
|
|
||||||
__RCSID("$MirOS: src/bin/mksh/edit.c,v 1.340 2017/08/27 23:33:50 tg Exp $");
|
__RCSID("$MirOS: src/bin/mksh/edit.c,v 1.342 2018/01/14 00:03:00 tg Exp $");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* in later versions we might use libtermcap for this, but since external
|
* in later versions we might use libtermcap for this, but since external
|
||||||
|
@ -312,12 +312,12 @@ x_glob_hlp_add_qchar(char *cp)
|
||||||
*/
|
*/
|
||||||
switch (ord(ch)) {
|
switch (ord(ch)) {
|
||||||
case QCHAR:
|
case QCHAR:
|
||||||
case ord('$'):
|
case ORD('$'):
|
||||||
case ord('*'):
|
case ORD('*'):
|
||||||
case ord('?'):
|
case ORD('?'):
|
||||||
case ord('['):
|
case ORD('['):
|
||||||
case ord('\\'):
|
case ORD('\\'):
|
||||||
case ord('`'):
|
case ORD('`'):
|
||||||
*dp++ = QCHAR;
|
*dp++ = QCHAR;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -650,11 +650,11 @@ x_cf_glob(int *flagsp, const char *buf, int buflen, int pos, int *startp,
|
||||||
if (*s == '\\' && s[1])
|
if (*s == '\\' && s[1])
|
||||||
s++;
|
s++;
|
||||||
else if (ctype(*s, C_QUEST | C_DOLAR) ||
|
else if (ctype(*s, C_QUEST | C_DOLAR) ||
|
||||||
ord(*s) == ord('*') || ord(*s) == ord('[') ||
|
ord(*s) == ORD('*') || ord(*s) == ORD('[') ||
|
||||||
/* ?() *() +() @() !() but two already checked */
|
/* ?() *() +() @() !() but two already checked */
|
||||||
(ord(s[1]) == ord('(' /*)*/) &&
|
(ord(s[1]) == ORD('(' /*)*/) &&
|
||||||
(ord(*s) == ord('+') || ord(*s) == ord('@') ||
|
(ord(*s) == ORD('+') || ord(*s) == ORD('@') ||
|
||||||
ord(*s) == ord('!')))) {
|
ord(*s) == ORD('!')))) {
|
||||||
/*
|
/*
|
||||||
* just expand based on the extglob
|
* just expand based on the extglob
|
||||||
* or parameter
|
* or parameter
|
||||||
|
@ -3688,7 +3688,7 @@ vi_hook(int ch)
|
||||||
return (1);
|
return (1);
|
||||||
cmdlen = 0;
|
cmdlen = 0;
|
||||||
argc1 = 0;
|
argc1 = 0;
|
||||||
if (ctype(ch, C_DIGIT) && ord(ch) != ord('0')) {
|
if (ctype(ch, C_DIGIT) && ord(ch) != ORD('0')) {
|
||||||
argc1 = ksh_numdig(ch);
|
argc1 = ksh_numdig(ch);
|
||||||
state = VARG1;
|
state = VARG1;
|
||||||
} else {
|
} else {
|
||||||
|
@ -3743,7 +3743,7 @@ vi_hook(int ch)
|
||||||
|
|
||||||
case VEXTCMD:
|
case VEXTCMD:
|
||||||
argc2 = 0;
|
argc2 = 0;
|
||||||
if (ctype(ch, C_DIGIT) && ord(ch) != ord('0')) {
|
if (ctype(ch, C_DIGIT) && ord(ch) != ORD('0')) {
|
||||||
argc2 = ksh_numdig(ch);
|
argc2 = ksh_numdig(ch);
|
||||||
state = VARG2;
|
state = VARG2;
|
||||||
return (0);
|
return (0);
|
||||||
|
@ -4128,7 +4128,7 @@ vi_cmd(int argcnt, const char *cmd)
|
||||||
redraw_line(true);
|
redraw_line(true);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ord('@'):
|
case ORD('@'):
|
||||||
{
|
{
|
||||||
static char alias[] = "_\0";
|
static char alias[] = "_\0";
|
||||||
struct tbl *ap;
|
struct tbl *ap;
|
||||||
|
@ -4169,7 +4169,7 @@ vi_cmd(int argcnt, const char *cmd)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ord('a'):
|
case ORD('a'):
|
||||||
modified = 1;
|
modified = 1;
|
||||||
hnum = hlast;
|
hnum = hlast;
|
||||||
if (vs->linelen != 0)
|
if (vs->linelen != 0)
|
||||||
|
@ -4177,7 +4177,7 @@ vi_cmd(int argcnt, const char *cmd)
|
||||||
insert = INSERT;
|
insert = INSERT;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ord('A'):
|
case ORD('A'):
|
||||||
modified = 1;
|
modified = 1;
|
||||||
hnum = hlast;
|
hnum = hlast;
|
||||||
del_range(0, 0);
|
del_range(0, 0);
|
||||||
|
@ -4185,7 +4185,7 @@ vi_cmd(int argcnt, const char *cmd)
|
||||||
insert = INSERT;
|
insert = INSERT;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ord('S'):
|
case ORD('S'):
|
||||||
vs->cursor = domovebeg();
|
vs->cursor = domovebeg();
|
||||||
del_range(vs->cursor, vs->linelen);
|
del_range(vs->cursor, vs->linelen);
|
||||||
modified = 1;
|
modified = 1;
|
||||||
|
@ -4193,14 +4193,14 @@ vi_cmd(int argcnt, const char *cmd)
|
||||||
insert = INSERT;
|
insert = INSERT;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ord('Y'):
|
case ORD('Y'):
|
||||||
cmd = "y$";
|
cmd = "y$";
|
||||||
/* ahhhhhh... */
|
/* ahhhhhh... */
|
||||||
|
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case ord('c'):
|
case ORD('c'):
|
||||||
case ord('d'):
|
case ORD('d'):
|
||||||
case ord('y'):
|
case ORD('y'):
|
||||||
if (*cmd == cmd[1]) {
|
if (*cmd == cmd[1]) {
|
||||||
c1 = *cmd == 'c' ? domovebeg() : 0;
|
c1 = *cmd == 'c' ? domovebeg() : 0;
|
||||||
c2 = vs->linelen;
|
c2 = vs->linelen;
|
||||||
|
@ -4239,7 +4239,7 @@ vi_cmd(int argcnt, const char *cmd)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ord('p'):
|
case ORD('p'):
|
||||||
modified = 1;
|
modified = 1;
|
||||||
hnum = hlast;
|
hnum = hlast;
|
||||||
if (vs->linelen != 0)
|
if (vs->linelen != 0)
|
||||||
|
@ -4253,7 +4253,7 @@ vi_cmd(int argcnt, const char *cmd)
|
||||||
return (-1);
|
return (-1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ord('P'):
|
case ORD('P'):
|
||||||
modified = 1;
|
modified = 1;
|
||||||
hnum = hlast;
|
hnum = hlast;
|
||||||
any = 0;
|
any = 0;
|
||||||
|
@ -4266,25 +4266,25 @@ vi_cmd(int argcnt, const char *cmd)
|
||||||
return (-1);
|
return (-1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ord('C'):
|
case ORD('C'):
|
||||||
modified = 1;
|
modified = 1;
|
||||||
hnum = hlast;
|
hnum = hlast;
|
||||||
del_range(vs->cursor, vs->linelen);
|
del_range(vs->cursor, vs->linelen);
|
||||||
insert = INSERT;
|
insert = INSERT;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ord('D'):
|
case ORD('D'):
|
||||||
yank_range(vs->cursor, vs->linelen);
|
yank_range(vs->cursor, vs->linelen);
|
||||||
del_range(vs->cursor, vs->linelen);
|
del_range(vs->cursor, vs->linelen);
|
||||||
if (vs->cursor != 0)
|
if (vs->cursor != 0)
|
||||||
vs->cursor--;
|
vs->cursor--;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ord('g'):
|
case ORD('g'):
|
||||||
if (!argcnt)
|
if (!argcnt)
|
||||||
argcnt = hlast;
|
argcnt = hlast;
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case ord('G'):
|
case ORD('G'):
|
||||||
if (!argcnt)
|
if (!argcnt)
|
||||||
argcnt = 1;
|
argcnt = 1;
|
||||||
else
|
else
|
||||||
|
@ -4297,21 +4297,21 @@ vi_cmd(int argcnt, const char *cmd)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ord('i'):
|
case ORD('i'):
|
||||||
modified = 1;
|
modified = 1;
|
||||||
hnum = hlast;
|
hnum = hlast;
|
||||||
insert = INSERT;
|
insert = INSERT;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ord('I'):
|
case ORD('I'):
|
||||||
modified = 1;
|
modified = 1;
|
||||||
hnum = hlast;
|
hnum = hlast;
|
||||||
vs->cursor = domovebeg();
|
vs->cursor = domovebeg();
|
||||||
insert = INSERT;
|
insert = INSERT;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ord('j'):
|
case ORD('j'):
|
||||||
case ord('+'):
|
case ORD('+'):
|
||||||
case CTRL_N:
|
case CTRL_N:
|
||||||
if (grabhist(modified, hnum + argcnt) < 0)
|
if (grabhist(modified, hnum + argcnt) < 0)
|
||||||
return (-1);
|
return (-1);
|
||||||
|
@ -4321,8 +4321,8 @@ vi_cmd(int argcnt, const char *cmd)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ord('k'):
|
case ORD('k'):
|
||||||
case ord('-'):
|
case ORD('-'):
|
||||||
case CTRL_P:
|
case CTRL_P:
|
||||||
if (grabhist(modified, hnum - argcnt) < 0)
|
if (grabhist(modified, hnum - argcnt) < 0)
|
||||||
return (-1);
|
return (-1);
|
||||||
|
@ -4332,7 +4332,7 @@ vi_cmd(int argcnt, const char *cmd)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ord('r'):
|
case ORD('r'):
|
||||||
if (vs->linelen == 0)
|
if (vs->linelen == 0)
|
||||||
return (-1);
|
return (-1);
|
||||||
modified = 1;
|
modified = 1;
|
||||||
|
@ -4350,13 +4350,13 @@ vi_cmd(int argcnt, const char *cmd)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ord('R'):
|
case ORD('R'):
|
||||||
modified = 1;
|
modified = 1;
|
||||||
hnum = hlast;
|
hnum = hlast;
|
||||||
insert = REPLACE;
|
insert = REPLACE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ord('s'):
|
case ORD('s'):
|
||||||
if (vs->linelen == 0)
|
if (vs->linelen == 0)
|
||||||
return (-1);
|
return (-1);
|
||||||
modified = 1;
|
modified = 1;
|
||||||
|
@ -4367,7 +4367,7 @@ vi_cmd(int argcnt, const char *cmd)
|
||||||
insert = INSERT;
|
insert = INSERT;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ord('v'):
|
case ORD('v'):
|
||||||
if (!argcnt) {
|
if (!argcnt) {
|
||||||
if (vs->linelen == 0)
|
if (vs->linelen == 0)
|
||||||
return (-1);
|
return (-1);
|
||||||
|
@ -4390,7 +4390,7 @@ vi_cmd(int argcnt, const char *cmd)
|
||||||
vs->linelen = strlen(vs->cbuf);
|
vs->linelen = strlen(vs->cbuf);
|
||||||
return (2);
|
return (2);
|
||||||
|
|
||||||
case ord('x'):
|
case ORD('x'):
|
||||||
if (vs->linelen == 0)
|
if (vs->linelen == 0)
|
||||||
return (-1);
|
return (-1);
|
||||||
modified = 1;
|
modified = 1;
|
||||||
|
@ -4401,7 +4401,7 @@ vi_cmd(int argcnt, const char *cmd)
|
||||||
del_range(vs->cursor, vs->cursor + argcnt);
|
del_range(vs->cursor, vs->cursor + argcnt);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ord('X'):
|
case ORD('X'):
|
||||||
if (vs->cursor > 0) {
|
if (vs->cursor > 0) {
|
||||||
modified = 1;
|
modified = 1;
|
||||||
hnum = hlast;
|
hnum = hlast;
|
||||||
|
@ -4414,13 +4414,13 @@ vi_cmd(int argcnt, const char *cmd)
|
||||||
return (-1);
|
return (-1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ord('u'):
|
case ORD('u'):
|
||||||
t = vs;
|
t = vs;
|
||||||
vs = undo;
|
vs = undo;
|
||||||
undo = t;
|
undo = t;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ord('U'):
|
case ORD('U'):
|
||||||
if (!modified)
|
if (!modified)
|
||||||
return (-1);
|
return (-1);
|
||||||
if (grabhist(modified, ohnum) < 0)
|
if (grabhist(modified, ohnum) < 0)
|
||||||
|
@ -4429,19 +4429,19 @@ vi_cmd(int argcnt, const char *cmd)
|
||||||
hnum = ohnum;
|
hnum = ohnum;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ord('?'):
|
case ORD('?'):
|
||||||
if (hnum == hlast)
|
if (hnum == hlast)
|
||||||
hnum = -1;
|
hnum = -1;
|
||||||
/* ahhh */
|
/* ahhh */
|
||||||
|
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case ord('/'):
|
case ORD('/'):
|
||||||
c3 = 1;
|
c3 = 1;
|
||||||
srchlen = 0;
|
srchlen = 0;
|
||||||
lastsearch = *cmd;
|
lastsearch = *cmd;
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case ord('n'):
|
case ORD('n'):
|
||||||
case ord('N'):
|
case ORD('N'):
|
||||||
if (lastsearch == ' ')
|
if (lastsearch == ' ')
|
||||||
return (-1);
|
return (-1);
|
||||||
if (lastsearch == '?')
|
if (lastsearch == '?')
|
||||||
|
@ -4468,7 +4468,7 @@ vi_cmd(int argcnt, const char *cmd)
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ord('_'):
|
case ORD('_'):
|
||||||
{
|
{
|
||||||
bool inspace;
|
bool inspace;
|
||||||
char *p, *sp;
|
char *p, *sp;
|
||||||
|
@ -4520,7 +4520,7 @@ vi_cmd(int argcnt, const char *cmd)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ord('~'):
|
case ORD('~'):
|
||||||
{
|
{
|
||||||
char *p;
|
char *p;
|
||||||
int i;
|
int i;
|
||||||
|
@ -4544,7 +4544,7 @@ vi_cmd(int argcnt, const char *cmd)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case ord('#'):
|
case ORD('#'):
|
||||||
{
|
{
|
||||||
int ret = x_do_comment(vs->cbuf, vs->cbufsize,
|
int ret = x_do_comment(vs->cbuf, vs->cbufsize,
|
||||||
&vs->linelen);
|
&vs->linelen);
|
||||||
|
@ -4554,7 +4554,7 @@ vi_cmd(int argcnt, const char *cmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* AT&T ksh */
|
/* AT&T ksh */
|
||||||
case ord('='):
|
case ORD('='):
|
||||||
/* Nonstandard vi/ksh */
|
/* Nonstandard vi/ksh */
|
||||||
case CTRL_E:
|
case CTRL_E:
|
||||||
print_expansions(vs, 1);
|
print_expansions(vs, 1);
|
||||||
|
@ -4574,7 +4574,7 @@ vi_cmd(int argcnt, const char *cmd)
|
||||||
return (-1);
|
return (-1);
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
/* AT&T ksh */
|
/* AT&T ksh */
|
||||||
case ord('\\'):
|
case ORD('\\'):
|
||||||
/* Nonstandard vi/ksh */
|
/* Nonstandard vi/ksh */
|
||||||
case CTRL_F:
|
case CTRL_F:
|
||||||
complete_word(1, argcnt);
|
complete_word(1, argcnt);
|
||||||
|
@ -4582,7 +4582,7 @@ vi_cmd(int argcnt, const char *cmd)
|
||||||
|
|
||||||
|
|
||||||
/* AT&T ksh */
|
/* AT&T ksh */
|
||||||
case ord('*'):
|
case ORD('*'):
|
||||||
/* Nonstandard vi/ksh */
|
/* Nonstandard vi/ksh */
|
||||||
case CTRL_X:
|
case CTRL_X:
|
||||||
expand_word(1);
|
expand_word(1);
|
||||||
|
@ -4590,8 +4590,8 @@ vi_cmd(int argcnt, const char *cmd)
|
||||||
|
|
||||||
|
|
||||||
/* mksh: cursor movement */
|
/* mksh: cursor movement */
|
||||||
case ord('['):
|
case ORD('['):
|
||||||
case ord('O'):
|
case ORD('O'):
|
||||||
state = VPREFIX2;
|
state = VPREFIX2;
|
||||||
if (vs->linelen != 0)
|
if (vs->linelen != 0)
|
||||||
vs->cursor++;
|
vs->cursor++;
|
||||||
|
@ -4611,19 +4611,19 @@ domove(int argcnt, const char *cmd, int sub)
|
||||||
unsigned int bcount;
|
unsigned int bcount;
|
||||||
|
|
||||||
switch (ord(*cmd)) {
|
switch (ord(*cmd)) {
|
||||||
case ord('b'):
|
case ORD('b'):
|
||||||
if (!sub && vs->cursor == 0)
|
if (!sub && vs->cursor == 0)
|
||||||
return (-1);
|
return (-1);
|
||||||
ncursor = backword(argcnt);
|
ncursor = backword(argcnt);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ord('B'):
|
case ORD('B'):
|
||||||
if (!sub && vs->cursor == 0)
|
if (!sub && vs->cursor == 0)
|
||||||
return (-1);
|
return (-1);
|
||||||
ncursor = Backword(argcnt);
|
ncursor = Backword(argcnt);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ord('e'):
|
case ORD('e'):
|
||||||
if (!sub && vs->cursor + 1 >= vs->linelen)
|
if (!sub && vs->cursor + 1 >= vs->linelen)
|
||||||
return (-1);
|
return (-1);
|
||||||
ncursor = endword(argcnt);
|
ncursor = endword(argcnt);
|
||||||
|
@ -4631,7 +4631,7 @@ domove(int argcnt, const char *cmd, int sub)
|
||||||
ncursor++;
|
ncursor++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ord('E'):
|
case ORD('E'):
|
||||||
if (!sub && vs->cursor + 1 >= vs->linelen)
|
if (!sub && vs->cursor + 1 >= vs->linelen)
|
||||||
return (-1);
|
return (-1);
|
||||||
ncursor = Endword(argcnt);
|
ncursor = Endword(argcnt);
|
||||||
|
@ -4639,15 +4639,15 @@ domove(int argcnt, const char *cmd, int sub)
|
||||||
ncursor++;
|
ncursor++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ord('f'):
|
case ORD('f'):
|
||||||
case ord('F'):
|
case ORD('F'):
|
||||||
case ord('t'):
|
case ORD('t'):
|
||||||
case ord('T'):
|
case ORD('T'):
|
||||||
fsavecmd = *cmd;
|
fsavecmd = *cmd;
|
||||||
fsavech = cmd[1];
|
fsavech = cmd[1];
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case ord(','):
|
case ORD(','):
|
||||||
case ord(';'):
|
case ORD(';'):
|
||||||
if (fsavecmd == ' ')
|
if (fsavecmd == ' ')
|
||||||
return (-1);
|
return (-1);
|
||||||
i = ksh_eq(fsavecmd, 'F', 'f');
|
i = ksh_eq(fsavecmd, 'F', 'f');
|
||||||
|
@ -4661,7 +4661,7 @@ domove(int argcnt, const char *cmd, int sub)
|
||||||
ncursor++;
|
ncursor++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ord('h'):
|
case ORD('h'):
|
||||||
case CTRL_H:
|
case CTRL_H:
|
||||||
if (!sub && vs->cursor == 0)
|
if (!sub && vs->cursor == 0)
|
||||||
return (-1);
|
return (-1);
|
||||||
|
@ -4670,8 +4670,8 @@ domove(int argcnt, const char *cmd, int sub)
|
||||||
ncursor = 0;
|
ncursor = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ord(' '):
|
case ORD(' '):
|
||||||
case ord('l'):
|
case ORD('l'):
|
||||||
if (!sub && vs->cursor + 1 >= vs->linelen)
|
if (!sub && vs->cursor + 1 >= vs->linelen)
|
||||||
return (-1);
|
return (-1);
|
||||||
if (vs->linelen != 0) {
|
if (vs->linelen != 0) {
|
||||||
|
@ -4681,27 +4681,27 @@ domove(int argcnt, const char *cmd, int sub)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ord('w'):
|
case ORD('w'):
|
||||||
if (!sub && vs->cursor + 1 >= vs->linelen)
|
if (!sub && vs->cursor + 1 >= vs->linelen)
|
||||||
return (-1);
|
return (-1);
|
||||||
ncursor = forwword(argcnt);
|
ncursor = forwword(argcnt);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ord('W'):
|
case ORD('W'):
|
||||||
if (!sub && vs->cursor + 1 >= vs->linelen)
|
if (!sub && vs->cursor + 1 >= vs->linelen)
|
||||||
return (-1);
|
return (-1);
|
||||||
ncursor = Forwword(argcnt);
|
ncursor = Forwword(argcnt);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ord('0'):
|
case ORD('0'):
|
||||||
ncursor = 0;
|
ncursor = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ord('^'):
|
case ORD('^'):
|
||||||
ncursor = domovebeg();
|
ncursor = domovebeg();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ord('|'):
|
case ORD('|'):
|
||||||
ncursor = argcnt;
|
ncursor = argcnt;
|
||||||
if (ncursor > vs->linelen)
|
if (ncursor > vs->linelen)
|
||||||
ncursor = vs->linelen;
|
ncursor = vs->linelen;
|
||||||
|
@ -4709,14 +4709,14 @@ domove(int argcnt, const char *cmd, int sub)
|
||||||
ncursor--;
|
ncursor--;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ord('$'):
|
case ORD('$'):
|
||||||
if (vs->linelen != 0)
|
if (vs->linelen != 0)
|
||||||
ncursor = vs->linelen;
|
ncursor = vs->linelen;
|
||||||
else
|
else
|
||||||
ncursor = 0;
|
ncursor = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ord('%'):
|
case ORD('%'):
|
||||||
ncursor = vs->cursor;
|
ncursor = vs->cursor;
|
||||||
while (ncursor < vs->linelen &&
|
while (ncursor < vs->linelen &&
|
||||||
(i = bracktype(vs->cbuf[ncursor])) == 0)
|
(i = bracktype(vs->cbuf[ncursor])) == 0)
|
||||||
|
@ -4784,22 +4784,22 @@ bracktype(int ch)
|
||||||
{
|
{
|
||||||
switch (ord(ch)) {
|
switch (ord(ch)) {
|
||||||
|
|
||||||
case ord('('):
|
case ORD('('):
|
||||||
return (1);
|
return (1);
|
||||||
|
|
||||||
case ord('['):
|
case ORD('['):
|
||||||
return (2);
|
return (2);
|
||||||
|
|
||||||
case ord('{'):
|
case ORD('{'):
|
||||||
return (3);
|
return (3);
|
||||||
|
|
||||||
case ord(')'):
|
case ORD(')'):
|
||||||
return (-1);
|
return (-1);
|
||||||
|
|
||||||
case ord(']'):
|
case ORD(']'):
|
||||||
return (-2);
|
return (-2);
|
||||||
|
|
||||||
case ord('}'):
|
case ORD('}'):
|
||||||
return (-3);
|
return (-3);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
248
src/eval.c
248
src/eval.c
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
|
* Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
|
||||||
* 2011, 2012, 2013, 2014, 2015, 2016, 2017
|
* 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018
|
||||||
* mirabilos <m@mirbsd.org>
|
* mirabilos <m@mirbsd.org>
|
||||||
*
|
*
|
||||||
* Provided that these terms and disclaimer and all copyright notices
|
* Provided that these terms and disclaimer and all copyright notices
|
||||||
|
@ -23,7 +23,7 @@
|
||||||
|
|
||||||
#include "sh.h"
|
#include "sh.h"
|
||||||
|
|
||||||
__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.215 2017/08/28 23:27:51 tg Exp $");
|
__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.219 2018/01/14 01:29:47 tg Exp $");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* string expansion
|
* string expansion
|
||||||
|
@ -320,21 +320,21 @@ expand(
|
||||||
case COMASUB:
|
case COMASUB:
|
||||||
case COMSUB:
|
case COMSUB:
|
||||||
*dp++ = '(';
|
*dp++ = '(';
|
||||||
c = ord(')');
|
c = ORD(')');
|
||||||
break;
|
break;
|
||||||
case FUNASUB:
|
case FUNASUB:
|
||||||
case FUNSUB:
|
case FUNSUB:
|
||||||
case VALSUB:
|
case VALSUB:
|
||||||
*dp++ = '{';
|
*dp++ = '{';
|
||||||
*dp++ = c == VALSUB ? '|' : ' ';
|
*dp++ = c == VALSUB ? '|' : ' ';
|
||||||
c = ord('}');
|
c = ORD('}');
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
while (*sp != '\0') {
|
while (*sp != '\0') {
|
||||||
Xcheck(ds, dp);
|
Xcheck(ds, dp);
|
||||||
*dp++ = *sp++;
|
*dp++ = *sp++;
|
||||||
}
|
}
|
||||||
if (c == ord('}'))
|
if ((unsigned int)c == ORD('}'))
|
||||||
*dp++ = ';';
|
*dp++ = ';';
|
||||||
*dp++ = c;
|
*dp++ = c;
|
||||||
} else {
|
} else {
|
||||||
|
@ -436,11 +436,11 @@ expand(
|
||||||
if (stype)
|
if (stype)
|
||||||
sp += slen;
|
sp += slen;
|
||||||
switch (stype & STYPE_SINGLE) {
|
switch (stype & STYPE_SINGLE) {
|
||||||
case ord('#') | STYPE_AT:
|
case ORD('#') | STYPE_AT:
|
||||||
x.str = shf_smprintf("%08X",
|
x.str = shf_smprintf("%08X",
|
||||||
(unsigned int)hash(str_val(st->var)));
|
(unsigned int)hash(str_val(st->var)));
|
||||||
break;
|
break;
|
||||||
case ord('Q') | STYPE_AT: {
|
case ORD('Q') | STYPE_AT: {
|
||||||
struct shf shf;
|
struct shf shf;
|
||||||
|
|
||||||
shf_sopen(NULL, 0, SHF_WR|SHF_DYNAMIC, &shf);
|
shf_sopen(NULL, 0, SHF_WR|SHF_DYNAMIC, &shf);
|
||||||
|
@ -448,7 +448,7 @@ expand(
|
||||||
x.str = shf_sclose(&shf);
|
x.str = shf_sclose(&shf);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ord('0'): {
|
case ORD('0'): {
|
||||||
char *beg, *mid, *end, *stg;
|
char *beg, *mid, *end, *stg;
|
||||||
mksh_ari_t from = 0, num = -1, flen, finc = 0;
|
mksh_ari_t from = 0, num = -1, flen, finc = 0;
|
||||||
|
|
||||||
|
@ -456,13 +456,13 @@ expand(
|
||||||
mid = beg + (wdscan(sp, ADELIM) - sp);
|
mid = beg + (wdscan(sp, ADELIM) - sp);
|
||||||
stg = beg + (wdscan(sp, CSUBST) - sp);
|
stg = beg + (wdscan(sp, CSUBST) - sp);
|
||||||
mid[-2] = EOS;
|
mid[-2] = EOS;
|
||||||
if (ord(mid[-1]) == ord(/*{*/ '}')) {
|
if (ord(mid[-1]) == ORD(/*{*/ '}')) {
|
||||||
sp += mid - beg - 1;
|
sp += mid - beg - 1;
|
||||||
end = NULL;
|
end = NULL;
|
||||||
} else {
|
} else {
|
||||||
end = mid +
|
end = mid +
|
||||||
(wdscan(mid, ADELIM) - mid);
|
(wdscan(mid, ADELIM) - mid);
|
||||||
if (ord(end[-1]) != ord(/*{*/ '}'))
|
if (ord(end[-1]) != ORD(/*{*/ '}'))
|
||||||
/* more than max delimiters */
|
/* more than max delimiters */
|
||||||
goto unwind_substsyn;
|
goto unwind_substsyn;
|
||||||
end[-2] = EOS;
|
end[-2] = EOS;
|
||||||
|
@ -495,8 +495,8 @@ expand(
|
||||||
strndupx(x.str, beg, num, ATEMP);
|
strndupx(x.str, beg, num, ATEMP);
|
||||||
goto do_CSUBST;
|
goto do_CSUBST;
|
||||||
}
|
}
|
||||||
case ord('/') | STYPE_AT:
|
case ORD('/') | STYPE_AT:
|
||||||
case ord('/'): {
|
case ORD('/'): {
|
||||||
char *s, *p, *d, *sbeg, *end;
|
char *s, *p, *d, *sbeg, *end;
|
||||||
char *pat = NULL, *rrep = null;
|
char *pat = NULL, *rrep = null;
|
||||||
char fpat = 0, *tpat1, *tpat2;
|
char fpat = 0, *tpat1, *tpat2;
|
||||||
|
@ -506,7 +506,7 @@ expand(
|
||||||
p = s + (wdscan(sp, ADELIM) - sp);
|
p = s + (wdscan(sp, ADELIM) - sp);
|
||||||
d = s + (wdscan(sp, CSUBST) - sp);
|
d = s + (wdscan(sp, CSUBST) - sp);
|
||||||
p[-2] = EOS;
|
p[-2] = EOS;
|
||||||
if (ord(p[-1]) == ord(/*{*/ '}'))
|
if (ord(p[-1]) == ORD(/*{*/ '}'))
|
||||||
d = NULL;
|
d = NULL;
|
||||||
else
|
else
|
||||||
d[-2] = EOS;
|
d[-2] = EOS;
|
||||||
|
@ -547,11 +547,11 @@ expand(
|
||||||
}
|
}
|
||||||
|
|
||||||
/* first see if we have any match at all */
|
/* first see if we have any match at all */
|
||||||
if (ord(fpat) == ord('#')) {
|
if (ord(fpat) == ORD('#')) {
|
||||||
/* anchor at the beginning */
|
/* anchor at the beginning */
|
||||||
tpat1 = shf_smprintf("%s%c*", pat, MAGIC);
|
tpat1 = shf_smprintf("%s%c*", pat, MAGIC);
|
||||||
tpat2 = tpat1;
|
tpat2 = tpat1;
|
||||||
} else if (ord(fpat) == ord('%')) {
|
} else if (ord(fpat) == ORD('%')) {
|
||||||
/* anchor at the end */
|
/* anchor at the end */
|
||||||
tpat1 = shf_smprintf("%c*%s", MAGIC, pat);
|
tpat1 = shf_smprintf("%c*%s", MAGIC, pat);
|
||||||
tpat2 = pat;
|
tpat2 = pat;
|
||||||
|
@ -569,7 +569,7 @@ expand(
|
||||||
goto end_repl;
|
goto end_repl;
|
||||||
end = strnul(s);
|
end = strnul(s);
|
||||||
/* now anchor the beginning of the match */
|
/* now anchor the beginning of the match */
|
||||||
if (ord(fpat) != ord('#'))
|
if (ord(fpat) != ORD('#'))
|
||||||
while (sbeg <= end) {
|
while (sbeg <= end) {
|
||||||
if (gmatchx(sbeg, tpat2, false))
|
if (gmatchx(sbeg, tpat2, false))
|
||||||
break;
|
break;
|
||||||
|
@ -578,11 +578,11 @@ expand(
|
||||||
}
|
}
|
||||||
/* now anchor the end of the match */
|
/* now anchor the end of the match */
|
||||||
p = end;
|
p = end;
|
||||||
if (ord(fpat) != ord('%'))
|
if (ord(fpat) != ORD('%'))
|
||||||
while (p >= sbeg) {
|
while (p >= sbeg) {
|
||||||
bool gotmatch;
|
bool gotmatch;
|
||||||
|
|
||||||
c = *p;
|
c = ord(*p);
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
gotmatch = tobool(gmatchx(sbeg, pat, false));
|
gotmatch = tobool(gmatchx(sbeg, pat, false));
|
||||||
*p = c;
|
*p = c;
|
||||||
|
@ -622,8 +622,8 @@ expand(
|
||||||
afree(ws, ATEMP);
|
afree(ws, ATEMP);
|
||||||
goto do_CSUBST;
|
goto do_CSUBST;
|
||||||
}
|
}
|
||||||
case ord('#'):
|
case ORD('#'):
|
||||||
case ord('%'):
|
case ORD('%'):
|
||||||
/* ! DOBLANK,DOBRACE */
|
/* ! DOBLANK,DOBRACE */
|
||||||
f = (f & DONTRUNCOMMAND) |
|
f = (f & DONTRUNCOMMAND) |
|
||||||
DOPAT | DOTILDE |
|
DOPAT | DOTILDE |
|
||||||
|
@ -637,10 +637,10 @@ expand(
|
||||||
*/
|
*/
|
||||||
if (!Flag(FSH)) {
|
if (!Flag(FSH)) {
|
||||||
*dp++ = MAGIC;
|
*dp++ = MAGIC;
|
||||||
*dp++ = ord(0x80 | '@');
|
*dp++ = ORD(0x80 | '@');
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ord('='):
|
case ORD('='):
|
||||||
/*
|
/*
|
||||||
* Tilde expansion for string
|
* Tilde expansion for string
|
||||||
* variables in POSIX mode is
|
* variables in POSIX mode is
|
||||||
|
@ -664,7 +664,7 @@ expand(
|
||||||
f &= ~(DOBLANK|DOGLOB|DOBRACE);
|
f &= ~(DOBLANK|DOGLOB|DOBRACE);
|
||||||
tilde_ok = 1;
|
tilde_ok = 1;
|
||||||
break;
|
break;
|
||||||
case ord('?'):
|
case ORD('?'):
|
||||||
if (*sp == CSUBST)
|
if (*sp == CSUBST)
|
||||||
errorf("%s: parameter null or not set",
|
errorf("%s: parameter null or not set",
|
||||||
st->var->name);
|
st->var->name);
|
||||||
|
@ -699,8 +699,8 @@ expand(
|
||||||
if (f & DOBLANK)
|
if (f & DOBLANK)
|
||||||
doblank--;
|
doblank--;
|
||||||
switch (st->stype & STYPE_SINGLE) {
|
switch (st->stype & STYPE_SINGLE) {
|
||||||
case ord('#'):
|
case ORD('#'):
|
||||||
case ord('%'):
|
case ORD('%'):
|
||||||
if (!Flag(FSH)) {
|
if (!Flag(FSH)) {
|
||||||
/* Append end-pattern */
|
/* Append end-pattern */
|
||||||
*dp++ = MAGIC;
|
*dp++ = MAGIC;
|
||||||
|
@ -730,7 +730,7 @@ expand(
|
||||||
doblank++;
|
doblank++;
|
||||||
st = st->prev;
|
st = st->prev;
|
||||||
continue;
|
continue;
|
||||||
case ord('='):
|
case ORD('='):
|
||||||
/*
|
/*
|
||||||
* Restore our position and substitute
|
* Restore our position and substitute
|
||||||
* the value of st->var (may not be
|
* the value of st->var (may not be
|
||||||
|
@ -763,17 +763,17 @@ expand(
|
||||||
st = st->prev;
|
st = st->prev;
|
||||||
word = quote || (!*x.str && (f & DOSCALAR)) ? IFS_WORD : IFS_IWS;
|
word = quote || (!*x.str && (f & DOSCALAR)) ? IFS_WORD : IFS_IWS;
|
||||||
continue;
|
continue;
|
||||||
case ord('?'):
|
case ORD('?'):
|
||||||
dp = Xrestpos(ds, dp, st->base);
|
dp = Xrestpos(ds, dp, st->base);
|
||||||
|
|
||||||
errorf(Tf_sD_s, st->var->name,
|
errorf(Tf_sD_s, st->var->name,
|
||||||
debunk(dp, dp, strlen(dp) + 1));
|
debunk(dp, dp, strlen(dp) + 1));
|
||||||
break;
|
break;
|
||||||
case ord('0'):
|
case ORD('0'):
|
||||||
case ord('/') | STYPE_AT:
|
case ORD('/') | STYPE_AT:
|
||||||
case ord('/'):
|
case ORD('/'):
|
||||||
case ord('#') | STYPE_AT:
|
case ORD('#') | STYPE_AT:
|
||||||
case ord('Q') | STYPE_AT:
|
case ORD('Q') | STYPE_AT:
|
||||||
dp = Xrestpos(ds, dp, st->base);
|
dp = Xrestpos(ds, dp, st->base);
|
||||||
type = XSUB;
|
type = XSUB;
|
||||||
word = quote || (!*x.str && (f & DOSCALAR)) ? IFS_WORD : IFS_IWS;
|
word = quote || (!*x.str && (f & DOSCALAR)) ? IFS_WORD : IFS_IWS;
|
||||||
|
@ -791,19 +791,19 @@ expand(
|
||||||
/* open pattern: *(foo|bar) */
|
/* open pattern: *(foo|bar) */
|
||||||
/* Next char is the type of pattern */
|
/* Next char is the type of pattern */
|
||||||
make_magic = true;
|
make_magic = true;
|
||||||
c = *sp++ | 0x80;
|
c = ord(*sp++) | 0x80U;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SPAT:
|
case SPAT:
|
||||||
/* pattern separator (|) */
|
/* pattern separator (|) */
|
||||||
make_magic = true;
|
make_magic = true;
|
||||||
c = '|';
|
c = ORD('|');
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CPAT:
|
case CPAT:
|
||||||
/* close pattern */
|
/* close pattern */
|
||||||
make_magic = true;
|
make_magic = true;
|
||||||
c = /*(*/ ')';
|
c = ORD(/*(*/ ')');
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -824,7 +824,7 @@ expand(
|
||||||
|
|
||||||
case XSUB:
|
case XSUB:
|
||||||
case XSUBMID:
|
case XSUBMID:
|
||||||
if ((c = *x.str++) == 0) {
|
if ((c = ord(*x.str++)) == 0) {
|
||||||
type = XBASE;
|
type = XBASE;
|
||||||
if (f & DOBLANK)
|
if (f & DOBLANK)
|
||||||
doblank--;
|
doblank--;
|
||||||
|
@ -837,7 +837,7 @@ expand(
|
||||||
quote = 1;
|
quote = 1;
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case XARG:
|
case XARG:
|
||||||
if ((c = *x.str++) == '\0') {
|
if ((c = ord(*x.str++)) == '\0') {
|
||||||
/*
|
/*
|
||||||
* force null words to be created so
|
* force null words to be created so
|
||||||
* set -- "" 2 ""; echo "$@" will do
|
* set -- "" 2 ""; echo "$@" will do
|
||||||
|
@ -855,13 +855,13 @@ expand(
|
||||||
if ((f & DOHEREDOC)) {
|
if ((f & DOHEREDOC)) {
|
||||||
/* pseudo-field-split reliably */
|
/* pseudo-field-split reliably */
|
||||||
if (c == 0)
|
if (c == 0)
|
||||||
c = ' ';
|
c = ORD(' ');
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if ((f & DOSCALAR)) {
|
if ((f & DOSCALAR)) {
|
||||||
/* do not field-split */
|
/* do not field-split */
|
||||||
if (x.split) {
|
if (x.split) {
|
||||||
c = ' ';
|
c = ORD(' ');
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (c == 0)
|
if (c == 0)
|
||||||
|
@ -873,7 +873,7 @@ expand(
|
||||||
if (!quote && word == IFS_WS)
|
if (!quote && word == IFS_WS)
|
||||||
continue;
|
continue;
|
||||||
/* this is so we don't terminate */
|
/* this is so we don't terminate */
|
||||||
c = ' ';
|
c = ORD(' ');
|
||||||
/* now force-emit a word */
|
/* now force-emit a word */
|
||||||
goto emit_word;
|
goto emit_word;
|
||||||
}
|
}
|
||||||
|
@ -893,33 +893,33 @@ expand(
|
||||||
c = -1;
|
c = -1;
|
||||||
} else if (newlines) {
|
} else if (newlines) {
|
||||||
/* spit out saved NLs */
|
/* spit out saved NLs */
|
||||||
c = '\n';
|
c = ORD('\n');
|
||||||
--newlines;
|
--newlines;
|
||||||
} else {
|
} else {
|
||||||
while ((c = shf_getc(x.u.shf)) == 0 ||
|
while ((c = shf_getc(x.u.shf)) == 0 ||
|
||||||
ctype(c, C_NL)) {
|
cinttype(c, C_NL)) {
|
||||||
#ifdef MKSH_WITH_TEXTMODE
|
#ifdef MKSH_WITH_TEXTMODE
|
||||||
if (c == '\r') {
|
if (c == ORD('\r')) {
|
||||||
c = shf_getc(x.u.shf);
|
c = shf_getc(x.u.shf);
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case '\n':
|
case ORD('\n'):
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
shf_ungetc(c, x.u.shf);
|
shf_ungetc(c, x.u.shf);
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case -1:
|
case -1:
|
||||||
c = '\r';
|
c = ORD('\r');
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (c == '\n')
|
if (c == ORD('\n'))
|
||||||
/* save newlines */
|
/* save newlines */
|
||||||
newlines++;
|
newlines++;
|
||||||
}
|
}
|
||||||
if (newlines && c != -1) {
|
if (newlines && c != -1) {
|
||||||
shf_ungetc(c, x.u.shf);
|
shf_ungetc(c, x.u.shf);
|
||||||
c = '\n';
|
c = ORD('\n');
|
||||||
--newlines;
|
--newlines;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1003,10 +1003,10 @@ expand(
|
||||||
/* mark any special second pass chars */
|
/* mark any special second pass chars */
|
||||||
if (!quote)
|
if (!quote)
|
||||||
switch (ord(c)) {
|
switch (ord(c)) {
|
||||||
case ord('['):
|
case ORD('['):
|
||||||
case ord('!'):
|
case ORD('!'):
|
||||||
case ord('-'):
|
case ORD('-'):
|
||||||
case ord(']'):
|
case ORD(']'):
|
||||||
/*
|
/*
|
||||||
* For character classes - doesn't hurt
|
* For character classes - doesn't hurt
|
||||||
* to have magic !,-,]s outside of
|
* to have magic !,-,]s outside of
|
||||||
|
@ -1014,29 +1014,29 @@ expand(
|
||||||
*/
|
*/
|
||||||
if (f & (DOPAT | DOGLOB)) {
|
if (f & (DOPAT | DOGLOB)) {
|
||||||
fdo |= DOMAGIC;
|
fdo |= DOMAGIC;
|
||||||
if (c == ord('['))
|
if ((unsigned int)c == ORD('['))
|
||||||
fdo |= f & DOGLOB;
|
fdo |= f & DOGLOB;
|
||||||
*dp++ = MAGIC;
|
*dp++ = MAGIC;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ord('*'):
|
case ORD('*'):
|
||||||
case ord('?'):
|
case ORD('?'):
|
||||||
if (f & (DOPAT | DOGLOB)) {
|
if (f & (DOPAT | DOGLOB)) {
|
||||||
fdo |= DOMAGIC | (f & DOGLOB);
|
fdo |= DOMAGIC | (f & DOGLOB);
|
||||||
*dp++ = MAGIC;
|
*dp++ = MAGIC;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ord('{'):
|
case ORD('{'):
|
||||||
case ord('}'):
|
case ORD('}'):
|
||||||
case ord(','):
|
case ORD(','):
|
||||||
if ((f & DOBRACE) &&
|
if ((f & DOBRACE) &&
|
||||||
(ord(c) == ord('{' /*}*/) ||
|
(ord(c) == ORD('{' /*}*/) ||
|
||||||
(fdo & DOBRACE))) {
|
(fdo & DOBRACE))) {
|
||||||
fdo |= DOBRACE|DOMAGIC;
|
fdo |= DOBRACE|DOMAGIC;
|
||||||
*dp++ = MAGIC;
|
*dp++ = MAGIC;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ord('='):
|
case ORD('='):
|
||||||
/* Note first unquoted = for ~ */
|
/* Note first unquoted = for ~ */
|
||||||
if (!(f & DOTEMP) && (!Flag(FPOSIX) ||
|
if (!(f & DOTEMP) && (!Flag(FPOSIX) ||
|
||||||
(f & DOASNTILDE)) && !saw_eq) {
|
(f & DOASNTILDE)) && !saw_eq) {
|
||||||
|
@ -1044,13 +1044,13 @@ expand(
|
||||||
tilde_ok = 1;
|
tilde_ok = 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ord(':'):
|
case ORD(':'):
|
||||||
/* : */
|
/* : */
|
||||||
/* Note unquoted : for ~ */
|
/* Note unquoted : for ~ */
|
||||||
if (!(f & DOTEMP) && (f & DOASNTILDE))
|
if (!(f & DOTEMP) && (f & DOASNTILDE))
|
||||||
tilde_ok = 1;
|
tilde_ok = 1;
|
||||||
break;
|
break;
|
||||||
case ord('~'):
|
case ORD('~'):
|
||||||
/*
|
/*
|
||||||
* tilde_ok is reset whenever
|
* tilde_ok is reset whenever
|
||||||
* any of ' " $( $(( ${ } are seen.
|
* any of ' " $( $(( ${ } are seen.
|
||||||
|
@ -1133,7 +1133,7 @@ varsub(Expand *xp, const char *sp, const char *word,
|
||||||
* ${%var}, string width (-U: screen columns, +U: octets)
|
* ${%var}, string width (-U: screen columns, +U: octets)
|
||||||
*/
|
*/
|
||||||
c = ord(sp[1]);
|
c = ord(sp[1]);
|
||||||
if (stype == ord('%') && c == '\0')
|
if ((unsigned int)stype == ORD('%') && c == '\0')
|
||||||
return (-1);
|
return (-1);
|
||||||
if (ctype(stype, C_SUB2) && c != '\0') {
|
if (ctype(stype, C_SUB2) && c != '\0') {
|
||||||
/* Can't have any modifiers for ${#...} or ${%...} */
|
/* Can't have any modifiers for ${#...} or ${%...} */
|
||||||
|
@ -1141,11 +1141,11 @@ varsub(Expand *xp, const char *sp, const char *word,
|
||||||
return (-1);
|
return (-1);
|
||||||
sp++;
|
sp++;
|
||||||
/* Check for size of array */
|
/* Check for size of array */
|
||||||
if ((p = cstrchr(sp, '[')) && (ord(p[1]) == ord('*') ||
|
if ((p = cstrchr(sp, '[')) && (ord(p[1]) == ORD('*') ||
|
||||||
ord(p[1]) == ord('@')) && ord(p[2]) == ord(']')) {
|
ord(p[1]) == ORD('@')) && ord(p[2]) == ORD(']')) {
|
||||||
int n = 0;
|
int n = 0;
|
||||||
|
|
||||||
if (stype != ord('#'))
|
if ((unsigned int)stype != ORD('#'))
|
||||||
return (-1);
|
return (-1);
|
||||||
vp = global(arrayname(sp));
|
vp = global(arrayname(sp));
|
||||||
if (vp->flag & (ISSET|ARRAY))
|
if (vp->flag & (ISSET|ARRAY))
|
||||||
|
@ -1154,14 +1154,15 @@ varsub(Expand *xp, const char *sp, const char *word,
|
||||||
if (vp->flag & ISSET)
|
if (vp->flag & ISSET)
|
||||||
n++;
|
n++;
|
||||||
c = n;
|
c = n;
|
||||||
} else if (c == ord('*') || c == ord('@')) {
|
} else if ((unsigned int)c == ORD('*') ||
|
||||||
if (stype != ord('#'))
|
(unsigned int)c == ORD('@')) {
|
||||||
|
if ((unsigned int)stype != ORD('#'))
|
||||||
return (-1);
|
return (-1);
|
||||||
c = e->loc->argc;
|
c = e->loc->argc;
|
||||||
} else {
|
} else {
|
||||||
p = str_val(global(sp));
|
p = str_val(global(sp));
|
||||||
zero_ok = p != null;
|
zero_ok = p != null;
|
||||||
if (stype == ord('#'))
|
if ((unsigned int)stype == ORD('#'))
|
||||||
c = utflen(p);
|
c = utflen(p);
|
||||||
else {
|
else {
|
||||||
/* partial utf_mbswidth reimplementation */
|
/* partial utf_mbswidth reimplementation */
|
||||||
|
@ -1196,11 +1197,11 @@ varsub(Expand *xp, const char *sp, const char *word,
|
||||||
xp->str = shf_smprintf(Tf_d, c);
|
xp->str = shf_smprintf(Tf_d, c);
|
||||||
return (XSUB);
|
return (XSUB);
|
||||||
}
|
}
|
||||||
if (stype == ord('!') && c != '\0' && *word == CSUBST) {
|
if ((unsigned int)stype == ORD('!') && c != '\0' && *word == CSUBST) {
|
||||||
sp++;
|
sp++;
|
||||||
if ((p = cstrchr(sp, '[')) && (ord(p[1]) == ord('*') ||
|
if ((p = cstrchr(sp, '[')) && (ord(p[1]) == ORD('*') ||
|
||||||
ord(p[1]) == ord('@')) && ord(p[2]) == ord(']')) {
|
ord(p[1]) == ORD('@')) && ord(p[2]) == ORD(']')) {
|
||||||
c = ord('!');
|
c = ORD('!');
|
||||||
stype = 0;
|
stype = 0;
|
||||||
goto arraynames;
|
goto arraynames;
|
||||||
}
|
}
|
||||||
|
@ -1214,12 +1215,12 @@ varsub(Expand *xp, const char *sp, const char *word,
|
||||||
/* Check for qualifiers in word part */
|
/* Check for qualifiers in word part */
|
||||||
stype = 0;
|
stype = 0;
|
||||||
c = word[slen + 0] == CHAR ? ord(word[slen + 1]) : 0;
|
c = word[slen + 0] == CHAR ? ord(word[slen + 1]) : 0;
|
||||||
if (c == ord(':')) {
|
if ((unsigned int)c == ORD(':')) {
|
||||||
slen += 2;
|
slen += 2;
|
||||||
stype = STYPE_DBL;
|
stype = STYPE_DBL;
|
||||||
c = word[slen + 0] == CHAR ? ord(word[slen + 1]) : 0;
|
c = word[slen + 0] == CHAR ? ord(word[slen + 1]) : 0;
|
||||||
}
|
}
|
||||||
if (!stype && c == ord('/')) {
|
if (!stype && (unsigned int)c == ORD('/')) {
|
||||||
slen += 2;
|
slen += 2;
|
||||||
stype = c;
|
stype = c;
|
||||||
if (word[slen] == ADELIM &&
|
if (word[slen] == ADELIM &&
|
||||||
|
@ -1227,8 +1228,9 @@ varsub(Expand *xp, const char *sp, const char *word,
|
||||||
slen += 2;
|
slen += 2;
|
||||||
stype |= STYPE_DBL;
|
stype |= STYPE_DBL;
|
||||||
}
|
}
|
||||||
} else if (stype == STYPE_DBL && (c == ord(' ') || c == ord('0'))) {
|
} else if (stype == STYPE_DBL && ((unsigned int)c == ORD(' ') ||
|
||||||
stype |= ord('0');
|
(unsigned int)c == ORD('0'))) {
|
||||||
|
stype |= ORD('0');
|
||||||
} else if (ctype(c, C_SUB1)) {
|
} else if (ctype(c, C_SUB1)) {
|
||||||
slen += 2;
|
slen += 2;
|
||||||
stype |= c;
|
stype |= c;
|
||||||
|
@ -1241,13 +1243,13 @@ varsub(Expand *xp, const char *sp, const char *word,
|
||||||
stype |= STYPE_DBL;
|
stype |= STYPE_DBL;
|
||||||
slen += 2;
|
slen += 2;
|
||||||
}
|
}
|
||||||
} else if (c == ord('@')) {
|
} else if ((unsigned int)c == ORD('@')) {
|
||||||
/* @x where x is command char */
|
/* @x where x is command char */
|
||||||
switch (c = ord(word[slen + 2]) == CHAR ?
|
switch (c = ord(word[slen + 2]) == CHAR ?
|
||||||
ord(word[slen + 3]) : 0) {
|
ord(word[slen + 3]) : 0) {
|
||||||
case ord('#'):
|
case ORD('#'):
|
||||||
case ord('/'):
|
case ORD('/'):
|
||||||
case ord('Q'):
|
case ORD('Q'):
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return (-1);
|
return (-1);
|
||||||
|
@ -1261,50 +1263,50 @@ varsub(Expand *xp, const char *sp, const char *word,
|
||||||
return (-1);
|
return (-1);
|
||||||
|
|
||||||
c = ord(sp[0]);
|
c = ord(sp[0]);
|
||||||
if (c == ord('*') || c == ord('@')) {
|
if ((unsigned int)c == ORD('*') || (unsigned int)c == ORD('@')) {
|
||||||
switch (stype & STYPE_SINGLE) {
|
switch (stype & STYPE_SINGLE) {
|
||||||
/* can't assign to a vector */
|
/* can't assign to a vector */
|
||||||
case ord('='):
|
case ORD('='):
|
||||||
/* can't trim a vector (yet) */
|
/* can't trim a vector (yet) */
|
||||||
case ord('%'):
|
case ORD('%'):
|
||||||
case ord('#'):
|
case ORD('#'):
|
||||||
case ord('?'):
|
case ORD('?'):
|
||||||
case ord('0'):
|
case ORD('0'):
|
||||||
case ord('/') | STYPE_AT:
|
case ORD('/') | STYPE_AT:
|
||||||
case ord('/'):
|
case ORD('/'):
|
||||||
case ord('#') | STYPE_AT:
|
case ORD('#') | STYPE_AT:
|
||||||
case ord('Q') | STYPE_AT:
|
case ORD('Q') | STYPE_AT:
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
if (e->loc->argc == 0) {
|
if (e->loc->argc == 0) {
|
||||||
xp->str = null;
|
xp->str = null;
|
||||||
xp->var = global(sp);
|
xp->var = global(sp);
|
||||||
state = c == ord('@') ? XNULLSUB : XSUB;
|
state = (unsigned int)c == ORD('@') ? XNULLSUB : XSUB;
|
||||||
} else {
|
} else {
|
||||||
xp->u.strv = (const char **)e->loc->argv + 1;
|
xp->u.strv = (const char **)e->loc->argv + 1;
|
||||||
xp->str = *xp->u.strv++;
|
xp->str = *xp->u.strv++;
|
||||||
/* $@ */
|
/* $@ */
|
||||||
xp->split = tobool(c == ord('@'));
|
xp->split = tobool((unsigned int)c == ORD('@'));
|
||||||
state = XARG;
|
state = XARG;
|
||||||
}
|
}
|
||||||
/* POSIX 2009? */
|
/* POSIX 2009? */
|
||||||
zero_ok = true;
|
zero_ok = true;
|
||||||
} else if ((p = cstrchr(sp, '[')) && (ord(p[1]) == ord('*') ||
|
} else if ((p = cstrchr(sp, '[')) && (ord(p[1]) == ORD('*') ||
|
||||||
ord(p[1]) == ord('@')) && ord(p[2]) == ord(']')) {
|
ord(p[1]) == ORD('@')) && ord(p[2]) == ORD(']')) {
|
||||||
XPtrV wv;
|
XPtrV wv;
|
||||||
|
|
||||||
switch (stype & STYPE_SINGLE) {
|
switch (stype & STYPE_SINGLE) {
|
||||||
/* can't assign to a vector */
|
/* can't assign to a vector */
|
||||||
case ord('='):
|
case ORD('='):
|
||||||
/* can't trim a vector (yet) */
|
/* can't trim a vector (yet) */
|
||||||
case ord('%'):
|
case ORD('%'):
|
||||||
case ord('#'):
|
case ORD('#'):
|
||||||
case ord('?'):
|
case ORD('?'):
|
||||||
case ord('0'):
|
case ORD('0'):
|
||||||
case ord('/') | STYPE_AT:
|
case ORD('/') | STYPE_AT:
|
||||||
case ord('/'):
|
case ORD('/'):
|
||||||
case ord('#') | STYPE_AT:
|
case ORD('#') | STYPE_AT:
|
||||||
case ord('Q') | STYPE_AT:
|
case ORD('Q') | STYPE_AT:
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
c = 0;
|
c = 0;
|
||||||
|
@ -1314,28 +1316,28 @@ varsub(Expand *xp, const char *sp, const char *word,
|
||||||
for (; vp; vp = vp->u.array) {
|
for (; vp; vp = vp->u.array) {
|
||||||
if (!(vp->flag&ISSET))
|
if (!(vp->flag&ISSET))
|
||||||
continue;
|
continue;
|
||||||
XPput(wv, c == ord('!') ? shf_smprintf(Tf_lu,
|
XPput(wv, (unsigned int)c == ORD('!') ?
|
||||||
arrayindex(vp)) :
|
shf_smprintf(Tf_lu, arrayindex(vp)) :
|
||||||
str_val(vp));
|
str_val(vp));
|
||||||
}
|
}
|
||||||
if (XPsize(wv) == 0) {
|
if (XPsize(wv) == 0) {
|
||||||
xp->str = null;
|
xp->str = null;
|
||||||
state = ord(p[1]) == ord('@') ? XNULLSUB : XSUB;
|
state = ord(p[1]) == ORD('@') ? XNULLSUB : XSUB;
|
||||||
XPfree(wv);
|
XPfree(wv);
|
||||||
} else {
|
} else {
|
||||||
XPput(wv, 0);
|
XPput(wv, 0);
|
||||||
xp->u.strv = (const char **)XPptrv(wv);
|
xp->u.strv = (const char **)XPptrv(wv);
|
||||||
xp->str = *xp->u.strv++;
|
xp->str = *xp->u.strv++;
|
||||||
/* ${foo[@]} */
|
/* ${foo[@]} */
|
||||||
xp->split = tobool(ord(p[1]) == ord('@'));
|
xp->split = tobool(ord(p[1]) == ORD('@'));
|
||||||
state = XARG;
|
state = XARG;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
xp->var = global(sp);
|
xp->var = global(sp);
|
||||||
xp->str = str_val(xp->var);
|
xp->str = str_val(xp->var);
|
||||||
/* can't assign things like $! or $1 */
|
/* can't assign things like $! or $1 */
|
||||||
if ((stype & STYPE_SINGLE) == ord('=') && !*xp->str &&
|
if ((unsigned int)(stype & STYPE_SINGLE) == ORD('=') &&
|
||||||
ctype(*sp, C_VAR1 | C_DIGIT))
|
!*xp->str && ctype(*sp, C_VAR1 | C_DIGIT))
|
||||||
return (-1);
|
return (-1);
|
||||||
state = XSUB;
|
state = XSUB;
|
||||||
}
|
}
|
||||||
|
@ -1346,13 +1348,15 @@ varsub(Expand *xp, const char *sp, const char *word,
|
||||||
(((stype & STYPE_DBL) ? *xp->str == '\0' : xp->str == null) &&
|
(((stype & STYPE_DBL) ? *xp->str == '\0' : xp->str == null) &&
|
||||||
(state != XARG || (ifs0 || xp->split ?
|
(state != XARG || (ifs0 || xp->split ?
|
||||||
(xp->u.strv[0] == NULL) : !hasnonempty(xp->u.strv))) ?
|
(xp->u.strv[0] == NULL) : !hasnonempty(xp->u.strv))) ?
|
||||||
ctype(c, C_EQUAL | C_MINUS | C_QUEST) : c == ord('+')))) ||
|
ctype(c, C_EQUAL | C_MINUS | C_QUEST) : (unsigned int)c == ORD('+')))) ||
|
||||||
stype == (ord('0') | STYPE_DBL) || stype == (ord('#') | STYPE_AT) ||
|
(unsigned int)stype == (ORD('0') | STYPE_DBL) ||
|
||||||
stype == (ord('Q') | STYPE_AT) || (stype & STYPE_CHAR) == ord('/'))
|
(unsigned int)stype == (ORD('#') | STYPE_AT) ||
|
||||||
|
(unsigned int)stype == (ORD('Q') | STYPE_AT) ||
|
||||||
|
(unsigned int)(stype & STYPE_CHAR) == ORD('/'))
|
||||||
/* expand word instead of variable value */
|
/* expand word instead of variable value */
|
||||||
state = XBASE;
|
state = XBASE;
|
||||||
if (Flag(FNOUNSET) && xp->str == null && !zero_ok &&
|
if (Flag(FNOUNSET) && xp->str == null && !zero_ok &&
|
||||||
(ctype(c, C_SUB2) || (state != XBASE && c != ord('+'))))
|
(ctype(c, C_SUB2) || (state != XBASE && (unsigned int)c != ORD('+'))))
|
||||||
errorf(Tf_parm, sp);
|
errorf(Tf_parm, sp);
|
||||||
*stypep = stype;
|
*stypep = stype;
|
||||||
*slenp = slen;
|
*slenp = slen;
|
||||||
|
@ -1491,7 +1495,7 @@ trimsub(char *str, char *pat, int how)
|
||||||
char *p, c;
|
char *p, c;
|
||||||
|
|
||||||
switch (how & (STYPE_CHAR | STYPE_DBL)) {
|
switch (how & (STYPE_CHAR | STYPE_DBL)) {
|
||||||
case ord('#'):
|
case ORD('#'):
|
||||||
/* shortest match at beginning */
|
/* shortest match at beginning */
|
||||||
for (p = str; p <= end; p += utf_ptradj(p)) {
|
for (p = str; p <= end; p += utf_ptradj(p)) {
|
||||||
c = *p; *p = '\0';
|
c = *p; *p = '\0';
|
||||||
|
@ -1503,7 +1507,7 @@ trimsub(char *str, char *pat, int how)
|
||||||
*p = c;
|
*p = c;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ord('#') | STYPE_DBL:
|
case ORD('#') | STYPE_DBL:
|
||||||
/* longest match at beginning */
|
/* longest match at beginning */
|
||||||
for (p = end; p >= str; p--) {
|
for (p = end; p >= str; p--) {
|
||||||
c = *p; *p = '\0';
|
c = *p; *p = '\0';
|
||||||
|
@ -1515,7 +1519,7 @@ trimsub(char *str, char *pat, int how)
|
||||||
*p = c;
|
*p = c;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ord('%'):
|
case ORD('%'):
|
||||||
/* shortest match at end */
|
/* shortest match at end */
|
||||||
p = end;
|
p = end;
|
||||||
while (p >= str) {
|
while (p >= str) {
|
||||||
|
@ -1531,7 +1535,7 @@ trimsub(char *str, char *pat, int how)
|
||||||
--p;
|
--p;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ord('%') | STYPE_DBL:
|
case ORD('%') | STYPE_DBL:
|
||||||
/* longest match at end */
|
/* longest match at end */
|
||||||
for (p = str; p <= end; p++)
|
for (p = str; p <= end; p++)
|
||||||
if (gmatchx(p, pat, false)) {
|
if (gmatchx(p, pat, false)) {
|
||||||
|
@ -1863,7 +1867,7 @@ alt_expand(XPtrV *wp, char *start, char *exp_start, char *end, int fdo)
|
||||||
char *p = exp_start;
|
char *p = exp_start;
|
||||||
|
|
||||||
/* search for open brace */
|
/* search for open brace */
|
||||||
while ((p = strchr(p, MAGIC)) && ord(p[1]) != ord('{' /*}*/))
|
while ((p = strchr(p, MAGIC)) && ord(p[1]) != ORD('{' /*}*/))
|
||||||
p += 2;
|
p += 2;
|
||||||
brace_start = p;
|
brace_start = p;
|
||||||
|
|
||||||
|
@ -1874,9 +1878,9 @@ alt_expand(XPtrV *wp, char *start, char *exp_start, char *end, int fdo)
|
||||||
p += 2;
|
p += 2;
|
||||||
while (*p && count) {
|
while (*p && count) {
|
||||||
if (ISMAGIC(*p++)) {
|
if (ISMAGIC(*p++)) {
|
||||||
if (ord(*p) == ord('{' /*}*/))
|
if (ord(*p) == ORD('{' /*}*/))
|
||||||
++count;
|
++count;
|
||||||
else if (ord(*p) == ord(/*{*/ '}'))
|
else if (ord(*p) == ORD(/*{*/ '}'))
|
||||||
--count;
|
--count;
|
||||||
else if (*p == ',' && count == 1)
|
else if (*p == ',' && count == 1)
|
||||||
comma = p;
|
comma = p;
|
||||||
|
@ -1908,9 +1912,9 @@ alt_expand(XPtrV *wp, char *start, char *exp_start, char *end, int fdo)
|
||||||
count = 1;
|
count = 1;
|
||||||
for (p = brace_start + 2; p != brace_end; p++) {
|
for (p = brace_start + 2; p != brace_end; p++) {
|
||||||
if (ISMAGIC(*p)) {
|
if (ISMAGIC(*p)) {
|
||||||
if (ord(*++p) == ord('{' /*}*/))
|
if (ord(*++p) == ORD('{' /*}*/))
|
||||||
++count;
|
++count;
|
||||||
else if ((ord(*p) == ord(/*{*/ '}') && --count == 0) ||
|
else if ((ord(*p) == ORD(/*{*/ '}') && --count == 0) ||
|
||||||
(*p == ',' && count == 1)) {
|
(*p == ',' && count == 1)) {
|
||||||
char *news;
|
char *news;
|
||||||
int l1, l2, l3;
|
int l1, l2, l3;
|
||||||
|
|
16
src/exec.c
16
src/exec.c
|
@ -23,7 +23,7 @@
|
||||||
|
|
||||||
#include "sh.h"
|
#include "sh.h"
|
||||||
|
|
||||||
__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.199 2017/08/07 21:16:31 tg Exp $");
|
__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.201 2017/10/11 21:09:24 tg Exp $");
|
||||||
|
|
||||||
#ifndef MKSH_DEFAULT_EXECSHELL
|
#ifndef MKSH_DEFAULT_EXECSHELL
|
||||||
#define MKSH_DEFAULT_EXECSHELL MKSH_UNIXROOT "/bin/sh"
|
#define MKSH_DEFAULT_EXECSHELL MKSH_UNIXROOT "/bin/sh"
|
||||||
|
@ -953,8 +953,12 @@ scriptexec(struct op *tp, const char **ap)
|
||||||
}
|
}
|
||||||
#ifdef __OS2__
|
#ifdef __OS2__
|
||||||
/*
|
/*
|
||||||
* Search shell/interpreter name without directory in PATH
|
* On OS/2, the directory structure differs from normal
|
||||||
* if specified path does not exist
|
* Unix, which can make many scripts whose shebang
|
||||||
|
* hardcodes the path to an interpreter fail (and there
|
||||||
|
* might be no /usr/bin/env); for user convenience, if
|
||||||
|
* the specified interpreter is not usable, do a PATH
|
||||||
|
* search to find it.
|
||||||
*/
|
*/
|
||||||
if (mksh_vdirsep(sh) && !search_path(sh, path, X_OK, NULL)) {
|
if (mksh_vdirsep(sh) && !search_path(sh, path, X_OK, NULL)) {
|
||||||
cp = search_path(_getname(sh), path, X_OK, NULL);
|
cp = search_path(_getname(sh), path, X_OK, NULL);
|
||||||
|
@ -1168,11 +1172,7 @@ findcom(const char *name, int flags)
|
||||||
char *fpath;
|
char *fpath;
|
||||||
union mksh_cchack npath;
|
union mksh_cchack npath;
|
||||||
|
|
||||||
if (mksh_vdirsep(name)
|
if (mksh_vdirsep(name)) {
|
||||||
#ifdef MKSH_DOSPATH
|
|
||||||
&& (strcmp(name, T_builtin) != 0)
|
|
||||||
#endif
|
|
||||||
) {
|
|
||||||
insert = 0;
|
insert = 0;
|
||||||
/* prevent FPATH search below */
|
/* prevent FPATH search below */
|
||||||
flags &= ~FC_FUNC;
|
flags &= ~FC_FUNC;
|
||||||
|
|
23
src/expr.c
23
src/expr.c
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
|
* Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
|
||||||
* 2011, 2012, 2013, 2014, 2016, 2017
|
* 2011, 2012, 2013, 2014, 2016, 2017, 2018
|
||||||
* mirabilos <m@mirbsd.org>
|
* mirabilos <m@mirbsd.org>
|
||||||
*
|
*
|
||||||
* Provided that these terms and disclaimer and all copyright notices
|
* Provided that these terms and disclaimer and all copyright notices
|
||||||
|
@ -23,7 +23,7 @@
|
||||||
|
|
||||||
#include "sh.h"
|
#include "sh.h"
|
||||||
|
|
||||||
__RCSID("$MirOS: src/bin/mksh/expr.c,v 1.100 2017/08/07 21:38:55 tg Exp $");
|
__RCSID("$MirOS: src/bin/mksh/expr.c,v 1.103 2018/01/14 01:29:47 tg Exp $");
|
||||||
|
|
||||||
#define EXPRTOK_DEFNS
|
#define EXPRTOK_DEFNS
|
||||||
#include "exprtok.h"
|
#include "exprtok.h"
|
||||||
|
@ -558,9 +558,11 @@ exprtoken(Expr_state *es)
|
||||||
|
|
||||||
/* skip whitespace */
|
/* skip whitespace */
|
||||||
skip_spaces:
|
skip_spaces:
|
||||||
while (ctype(ord((c = *cp)), C_SPACE))
|
--cp;
|
||||||
++cp;
|
do {
|
||||||
if (es->tokp == es->expression && c == ord('#')) {
|
c = ord(*++cp);
|
||||||
|
} while (ctype(c, C_SPACE));
|
||||||
|
if (es->tokp == es->expression && (unsigned int)c == ORD('#')) {
|
||||||
/* expression begins with # */
|
/* expression begins with # */
|
||||||
/* switch to unsigned */
|
/* switch to unsigned */
|
||||||
es->natural = true;
|
es->natural = true;
|
||||||
|
@ -575,7 +577,7 @@ exprtoken(Expr_state *es)
|
||||||
do {
|
do {
|
||||||
c = ord(*++cp);
|
c = ord(*++cp);
|
||||||
} while (ctype(c, C_ALNUX));
|
} while (ctype(c, C_ALNUX));
|
||||||
if (c == ord('[')) {
|
if ((unsigned int)c == ORD('[')) {
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
len = array_ref_len(cp);
|
len = array_ref_len(cp);
|
||||||
|
@ -884,7 +886,7 @@ static int mb_ucsbsearch(const struct mb_ucsrange arr[], size_t elems,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Generated from the Unicode Character Database, Version 10.0.0, by
|
* Generated from the Unicode Character Database, Version 10.0.0, by
|
||||||
* MirOS: contrib/code/Snippets/eawparse,v 1.10 2017/07/12 22:47:26 tg Exp $
|
* MirOS: contrib/code/Snippets/eawparse,v 1.12 2017/09/06 16:05:45 tg Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static const struct mb_ucsrange mb_ucs_combining[] = {
|
static const struct mb_ucsrange mb_ucs_combining[] = {
|
||||||
|
@ -895,16 +897,14 @@ static const struct mb_ucsrange mb_ucs_combining[] = {
|
||||||
{ 0x05C1, 0x05C2 },
|
{ 0x05C1, 0x05C2 },
|
||||||
{ 0x05C4, 0x05C5 },
|
{ 0x05C4, 0x05C5 },
|
||||||
{ 0x05C7, 0x05C7 },
|
{ 0x05C7, 0x05C7 },
|
||||||
{ 0x0600, 0x0605 },
|
|
||||||
{ 0x0610, 0x061A },
|
{ 0x0610, 0x061A },
|
||||||
{ 0x061C, 0x061C },
|
{ 0x061C, 0x061C },
|
||||||
{ 0x064B, 0x065F },
|
{ 0x064B, 0x065F },
|
||||||
{ 0x0670, 0x0670 },
|
{ 0x0670, 0x0670 },
|
||||||
{ 0x06D6, 0x06DD },
|
{ 0x06D6, 0x06DC },
|
||||||
{ 0x06DF, 0x06E4 },
|
{ 0x06DF, 0x06E4 },
|
||||||
{ 0x06E7, 0x06E8 },
|
{ 0x06E7, 0x06E8 },
|
||||||
{ 0x06EA, 0x06ED },
|
{ 0x06EA, 0x06ED },
|
||||||
{ 0x070F, 0x070F },
|
|
||||||
{ 0x0711, 0x0711 },
|
{ 0x0711, 0x0711 },
|
||||||
{ 0x0730, 0x074A },
|
{ 0x0730, 0x074A },
|
||||||
{ 0x07A6, 0x07B0 },
|
{ 0x07A6, 0x07B0 },
|
||||||
|
@ -914,7 +914,8 @@ static const struct mb_ucsrange mb_ucs_combining[] = {
|
||||||
{ 0x0825, 0x0827 },
|
{ 0x0825, 0x0827 },
|
||||||
{ 0x0829, 0x082D },
|
{ 0x0829, 0x082D },
|
||||||
{ 0x0859, 0x085B },
|
{ 0x0859, 0x085B },
|
||||||
{ 0x08D4, 0x0902 },
|
{ 0x08D4, 0x08E1 },
|
||||||
|
{ 0x08E3, 0x0902 },
|
||||||
{ 0x093A, 0x093A },
|
{ 0x093A, 0x093A },
|
||||||
{ 0x093C, 0x093C },
|
{ 0x093C, 0x093C },
|
||||||
{ 0x0941, 0x0948 },
|
{ 0x0941, 0x0948 },
|
||||||
|
|
16
src/funcs.c
16
src/funcs.c
|
@ -38,7 +38,7 @@
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.350 2017/05/05 22:53:28 tg Exp $");
|
__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.353 2018/01/14 01:26:49 tg Exp $");
|
||||||
|
|
||||||
#if HAVE_KILLPG
|
#if HAVE_KILLPG
|
||||||
/*
|
/*
|
||||||
|
@ -594,7 +594,7 @@ c_print(const char **wp)
|
||||||
static int
|
static int
|
||||||
s_get(void)
|
s_get(void)
|
||||||
{
|
{
|
||||||
return (*s_ptr++);
|
return (ord(*s_ptr++));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -751,9 +751,9 @@ do_whence(const char **wp, int fcflags, bool vflag, bool iscommand)
|
||||||
bool
|
bool
|
||||||
valid_alias_name(const char *cp)
|
valid_alias_name(const char *cp)
|
||||||
{
|
{
|
||||||
if (ord(*cp) == ord('-'))
|
if (ord(*cp) == ORD('-'))
|
||||||
return (false);
|
return (false);
|
||||||
if (ord(cp[0]) == ord('[') && ord(cp[1]) == ord('[') && !cp[2])
|
if (ord(cp[0]) == ORD('[') && ord(cp[1]) == ORD('[') && !cp[2])
|
||||||
return (false);
|
return (false);
|
||||||
while (*cp)
|
while (*cp)
|
||||||
if (ctype(*cp, C_ALIAS))
|
if (ctype(*cp, C_ALIAS))
|
||||||
|
@ -2304,9 +2304,9 @@ c_unset(const char **wp)
|
||||||
size_t n;
|
size_t n;
|
||||||
|
|
||||||
n = strlen(id);
|
n = strlen(id);
|
||||||
if (n > 3 && ord(id[n - 3]) == ord('[') &&
|
if (n > 3 && ord(id[n - 3]) == ORD('[') &&
|
||||||
ord(id[n - 2]) == ord('*') &&
|
ord(id[n - 2]) == ORD('*') &&
|
||||||
ord(id[n - 1]) == ord(']')) {
|
ord(id[n - 1]) == ORD(']')) {
|
||||||
strndupx(cp, id, n - 3, ATEMP);
|
strndupx(cp, id, n - 3, ATEMP);
|
||||||
id = cp;
|
id = cp;
|
||||||
optc = 3;
|
optc = 3;
|
||||||
|
@ -3539,7 +3539,7 @@ c_cat(const char **wp)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (errno == EPIPE) {
|
if (errno == EPIPE) {
|
||||||
/* fake receiving signel */
|
/* fake receiving signal */
|
||||||
rv = ksh_sigmask(SIGPIPE);
|
rv = ksh_sigmask(SIGPIPE);
|
||||||
} else {
|
} else {
|
||||||
/* an error occured during writing */
|
/* an error occured during writing */
|
||||||
|
|
23
src/jobs.c
23
src/jobs.c
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2011,
|
* Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2011,
|
||||||
* 2012, 2013, 2014, 2015, 2016
|
* 2012, 2013, 2014, 2015, 2016, 2018
|
||||||
* mirabilos <m@mirbsd.org>
|
* mirabilos <m@mirbsd.org>
|
||||||
*
|
*
|
||||||
* Provided that these terms and disclaimer and all copyright notices
|
* Provided that these terms and disclaimer and all copyright notices
|
||||||
|
@ -23,7 +23,7 @@
|
||||||
|
|
||||||
#include "sh.h"
|
#include "sh.h"
|
||||||
|
|
||||||
__RCSID("$MirOS: src/bin/mksh/jobs.c,v 1.124 2017/08/08 14:30:10 tg Exp $");
|
__RCSID("$MirOS: src/bin/mksh/jobs.c,v 1.125 2018/01/05 20:08:34 tg Exp $");
|
||||||
|
|
||||||
#if HAVE_KILLPG
|
#if HAVE_KILLPG
|
||||||
#define mksh_killpg killpg
|
#define mksh_killpg killpg
|
||||||
|
@ -1545,7 +1545,9 @@ j_print(Job *j, int how, struct shf *shf)
|
||||||
Proc *p;
|
Proc *p;
|
||||||
int state;
|
int state;
|
||||||
int status;
|
int status;
|
||||||
|
#ifdef WCOREDUMP
|
||||||
bool coredumped;
|
bool coredumped;
|
||||||
|
#endif
|
||||||
char jobchar = ' ';
|
char jobchar = ' ';
|
||||||
char buf[64];
|
char buf[64];
|
||||||
const char *filler;
|
const char *filler;
|
||||||
|
@ -1569,7 +1571,9 @@ j_print(Job *j, int how, struct shf *shf)
|
||||||
jobchar = '-';
|
jobchar = '-';
|
||||||
|
|
||||||
for (p = j->proc_list; p != NULL;) {
|
for (p = j->proc_list; p != NULL;) {
|
||||||
|
#ifdef WCOREDUMP
|
||||||
coredumped = false;
|
coredumped = false;
|
||||||
|
#endif
|
||||||
switch (p->state) {
|
switch (p->state) {
|
||||||
case PRUNNING:
|
case PRUNNING:
|
||||||
memcpy(buf, "Running", 8);
|
memcpy(buf, "Running", 8);
|
||||||
|
@ -1603,7 +1607,10 @@ j_print(Job *j, int how, struct shf *shf)
|
||||||
* kludge for not reporting 'normal termination
|
* kludge for not reporting 'normal termination
|
||||||
* signals' (i.e. SIGINT, SIGPIPE)
|
* signals' (i.e. SIGINT, SIGPIPE)
|
||||||
*/
|
*/
|
||||||
if (how == JP_SHORT && !coredumped &&
|
if (how == JP_SHORT &&
|
||||||
|
#ifdef WCOREDUMP
|
||||||
|
!coredumped &&
|
||||||
|
#endif
|
||||||
(termsig == SIGINT || termsig == SIGPIPE)) {
|
(termsig == SIGINT || termsig == SIGPIPE)) {
|
||||||
buf[0] = '\0';
|
buf[0] = '\0';
|
||||||
} else
|
} else
|
||||||
|
@ -1629,14 +1636,22 @@ j_print(Job *j, int how, struct shf *shf)
|
||||||
if (how == JP_SHORT) {
|
if (how == JP_SHORT) {
|
||||||
if (buf[0]) {
|
if (buf[0]) {
|
||||||
output = 1;
|
output = 1;
|
||||||
|
#ifdef WCOREDUMP
|
||||||
shf_fprintf(shf, "%s%s ",
|
shf_fprintf(shf, "%s%s ",
|
||||||
buf, coredumped ? " (core dumped)" : null);
|
buf, coredumped ? " (core dumped)" : null);
|
||||||
|
#else
|
||||||
|
shf_puts(buf, shf);
|
||||||
|
shf_putchar(' ', shf);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
output = 1;
|
output = 1;
|
||||||
shf_fprintf(shf, "%-20s %s%s%s", buf, p->command,
|
shf_fprintf(shf, "%-20s %s%s%s", buf, p->command,
|
||||||
p->next ? "|" : null,
|
p->next ? "|" : null,
|
||||||
coredumped ? " (core dumped)" : null);
|
#ifdef WCOREDUMP
|
||||||
|
coredumped ? " (core dumped)" :
|
||||||
|
#endif
|
||||||
|
null);
|
||||||
}
|
}
|
||||||
|
|
||||||
state = p->state;
|
state = p->state;
|
||||||
|
|
250
src/lex.c
250
src/lex.c
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
|
* Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
|
||||||
* 2011, 2012, 2013, 2014, 2015, 2016, 2017
|
* 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018
|
||||||
* mirabilos <m@mirbsd.org>
|
* mirabilos <m@mirbsd.org>
|
||||||
*
|
*
|
||||||
* Provided that these terms and disclaimer and all copyright notices
|
* Provided that these terms and disclaimer and all copyright notices
|
||||||
|
@ -23,7 +23,7 @@
|
||||||
|
|
||||||
#include "sh.h"
|
#include "sh.h"
|
||||||
|
|
||||||
__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.239 2017/05/05 22:53:29 tg Exp $");
|
__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.247 2018/01/14 01:44:01 tg Exp $");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* states while lexing word
|
* states while lexing word
|
||||||
|
@ -127,11 +127,11 @@ static int ignore_backslash_newline;
|
||||||
static int
|
static int
|
||||||
getsc_i(void)
|
getsc_i(void)
|
||||||
{
|
{
|
||||||
o_getsc_r(o_getsc());
|
o_getsc_r((unsigned int)(unsigned char)o_getsc());
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(MKSH_SMALL) && !defined(MKSH_SMALL_BUT_FAST)
|
#if defined(MKSH_SMALL) && !defined(MKSH_SMALL_BUT_FAST)
|
||||||
#define getsc() ord(getsc_i())
|
#define getsc() getsc_i()
|
||||||
#else
|
#else
|
||||||
static int getsc_r(int);
|
static int getsc_r(int);
|
||||||
|
|
||||||
|
@ -141,7 +141,7 @@ getsc_r(int c)
|
||||||
o_getsc_r(c);
|
o_getsc_r(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define getsc() ord(getsc_r(o_getsc()))
|
#define getsc() getsc_r((unsigned int)(unsigned char)o_getsc())
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define STATE_BSIZE 8
|
#define STATE_BSIZE 8
|
||||||
|
@ -220,12 +220,14 @@ yylex(int cf)
|
||||||
} else {
|
} else {
|
||||||
/* normal lexing */
|
/* normal lexing */
|
||||||
state = (cf & HEREDELIM) ? SHEREDELIM : SBASE;
|
state = (cf & HEREDELIM) ? SHEREDELIM : SBASE;
|
||||||
while (ctype((c = getsc()), C_BLANK))
|
do {
|
||||||
;
|
c = getsc();
|
||||||
|
} while (ctype(c, C_BLANK));
|
||||||
if (c == '#') {
|
if (c == '#') {
|
||||||
ignore_backslash_newline++;
|
ignore_backslash_newline++;
|
||||||
while (!ctype((c = getsc()), C_NUL | C_LF))
|
do {
|
||||||
;
|
c = getsc();
|
||||||
|
} while (!ctype(c, C_NUL | C_LF));
|
||||||
ignore_backslash_newline--;
|
ignore_backslash_newline--;
|
||||||
}
|
}
|
||||||
ungetsc(c);
|
ungetsc(c);
|
||||||
|
@ -245,30 +247,32 @@ yylex(int cf)
|
||||||
while (!((c = getsc()) == 0 ||
|
while (!((c = getsc()) == 0 ||
|
||||||
((state == SBASE || state == SHEREDELIM) && ctype(c, C_LEX1)))) {
|
((state == SBASE || state == SHEREDELIM) && ctype(c, C_LEX1)))) {
|
||||||
if (state == SBASE &&
|
if (state == SBASE &&
|
||||||
subshell_nesting_type == ord(/*{*/ '}') &&
|
subshell_nesting_type == ORD(/*{*/ '}') &&
|
||||||
c == ord(/*{*/ '}'))
|
(unsigned int)c == ORD(/*{*/ '}'))
|
||||||
/* possibly end ${ :;} */
|
/* possibly end ${ :;} */
|
||||||
break;
|
break;
|
||||||
Xcheck(ws, wp);
|
Xcheck(ws, wp);
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case SADELIM:
|
case SADELIM:
|
||||||
if (c == ord('('))
|
if ((unsigned int)c == ORD('('))
|
||||||
statep->nparen++;
|
statep->nparen++;
|
||||||
else if (c == ord(')'))
|
else if ((unsigned int)c == ORD(')'))
|
||||||
statep->nparen--;
|
statep->nparen--;
|
||||||
else if (statep->nparen == 0 && (c == ord(/*{*/ '}') ||
|
else if (statep->nparen == 0 &&
|
||||||
|
((unsigned int)c == ORD(/*{*/ '}') ||
|
||||||
c == (int)statep->ls_adelim.delimiter)) {
|
c == (int)statep->ls_adelim.delimiter)) {
|
||||||
*wp++ = ADELIM;
|
*wp++ = ADELIM;
|
||||||
*wp++ = c;
|
*wp++ = c;
|
||||||
if (c == ord(/*{*/ '}') || --statep->ls_adelim.num == 0)
|
if ((unsigned int)c == ORD(/*{*/ '}') ||
|
||||||
|
--statep->ls_adelim.num == 0)
|
||||||
POP_STATE();
|
POP_STATE();
|
||||||
if (c == ord(/*{*/ '}'))
|
if ((unsigned int)c == ORD(/*{*/ '}'))
|
||||||
POP_STATE();
|
POP_STATE();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case SBASE:
|
case SBASE:
|
||||||
if (c == ord('[') && (cf & CMDASN)) {
|
if ((unsigned int)c == ORD('[') && (cf & CMDASN)) {
|
||||||
/* temporary */
|
/* temporary */
|
||||||
*wp = EOS;
|
*wp = EOS;
|
||||||
if (is_wdvarname(Xstring(ws, wp), false)) {
|
if (is_wdvarname(Xstring(ws, wp), false)) {
|
||||||
|
@ -284,15 +288,6 @@ yylex(int cf)
|
||||||
}
|
}
|
||||||
afree(tmp, ATEMP);
|
afree(tmp, ATEMP);
|
||||||
break;
|
break;
|
||||||
} else {
|
|
||||||
Source *s;
|
|
||||||
|
|
||||||
s = pushs(SREREAD,
|
|
||||||
source->areap);
|
|
||||||
s->start = s->str =
|
|
||||||
s->u.freeme = tmp;
|
|
||||||
s->next = source;
|
|
||||||
source = s;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*wp++ = CHAR;
|
*wp++ = CHAR;
|
||||||
|
@ -303,7 +298,7 @@ yylex(int cf)
|
||||||
Sbase1: /* includes *(...|...) pattern (*+?@!) */
|
Sbase1: /* includes *(...|...) pattern (*+?@!) */
|
||||||
if (ctype(c, C_PATMO)) {
|
if (ctype(c, C_PATMO)) {
|
||||||
c2 = getsc();
|
c2 = getsc();
|
||||||
if (c2 == ord('(' /*)*/)) {
|
if ((unsigned int)c2 == ORD('(' /*)*/)) {
|
||||||
*wp++ = OPAT;
|
*wp++ = OPAT;
|
||||||
*wp++ = c;
|
*wp++ = c;
|
||||||
PUSH_STATE(SPATTERN);
|
PUSH_STATE(SPATTERN);
|
||||||
|
@ -314,7 +309,7 @@ yylex(int cf)
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
Sbase2: /* doesn't include *(...|...) pattern (*+?@!) */
|
Sbase2: /* doesn't include *(...|...) pattern (*+?@!) */
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case ord('\\'):
|
case ORD('\\'):
|
||||||
getsc_qchar:
|
getsc_qchar:
|
||||||
if ((c = getsc())) {
|
if ((c = getsc())) {
|
||||||
/* trailing \ is lost */
|
/* trailing \ is lost */
|
||||||
|
@ -322,7 +317,7 @@ yylex(int cf)
|
||||||
*wp++ = c;
|
*wp++ = c;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ord('\''):
|
case ORD('\''):
|
||||||
open_ssquote_unless_heredoc:
|
open_ssquote_unless_heredoc:
|
||||||
if ((cf & HEREDOC))
|
if ((cf & HEREDOC))
|
||||||
goto store_char;
|
goto store_char;
|
||||||
|
@ -330,12 +325,12 @@ yylex(int cf)
|
||||||
ignore_backslash_newline++;
|
ignore_backslash_newline++;
|
||||||
PUSH_STATE(SSQUOTE);
|
PUSH_STATE(SSQUOTE);
|
||||||
break;
|
break;
|
||||||
case ord('"'):
|
case ORD('"'):
|
||||||
open_sdquote:
|
open_sdquote:
|
||||||
*wp++ = OQUOTE;
|
*wp++ = OQUOTE;
|
||||||
PUSH_STATE(SDQUOTE);
|
PUSH_STATE(SDQUOTE);
|
||||||
break;
|
break;
|
||||||
case ord('$'):
|
case ORD('$'):
|
||||||
/*
|
/*
|
||||||
* processing of dollar sign belongs into
|
* processing of dollar sign belongs into
|
||||||
* Subst, except for those which can open
|
* Subst, except for those which can open
|
||||||
|
@ -344,9 +339,9 @@ yylex(int cf)
|
||||||
subst_dollar_ex:
|
subst_dollar_ex:
|
||||||
c = getsc();
|
c = getsc();
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case ord('"'):
|
case ORD('"'):
|
||||||
goto open_sdquote;
|
goto open_sdquote;
|
||||||
case ord('\''):
|
case ORD('\''):
|
||||||
goto open_sequote;
|
goto open_sequote;
|
||||||
default:
|
default:
|
||||||
goto SubstS;
|
goto SubstS;
|
||||||
|
@ -358,16 +353,16 @@ yylex(int cf)
|
||||||
|
|
||||||
Subst:
|
Subst:
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case ord('\\'):
|
case ORD('\\'):
|
||||||
c = getsc();
|
c = getsc();
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case ord('"'):
|
case ORD('"'):
|
||||||
if ((cf & HEREDOC))
|
if ((cf & HEREDOC))
|
||||||
goto heredocquote;
|
goto heredocquote;
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case ord('\\'):
|
case ORD('\\'):
|
||||||
case ord('$'):
|
case ORD('$'):
|
||||||
case ord('`'):
|
case ORD('`'):
|
||||||
store_qchar:
|
store_qchar:
|
||||||
*wp++ = QCHAR;
|
*wp++ = QCHAR;
|
||||||
*wp++ = c;
|
*wp++ = c;
|
||||||
|
@ -385,12 +380,12 @@ yylex(int cf)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ord('$'):
|
case ORD('$'):
|
||||||
c = getsc();
|
c = getsc();
|
||||||
SubstS:
|
SubstS:
|
||||||
if (c == ord('(' /*)*/)) {
|
if ((unsigned int)c == ORD('(' /*)*/)) {
|
||||||
c = getsc();
|
c = getsc();
|
||||||
if (c == ord('(' /*)*/)) {
|
if ((unsigned int)c == ORD('(' /*)*/)) {
|
||||||
*wp++ = EXPRSUB;
|
*wp++ = EXPRSUB;
|
||||||
PUSH_SRETRACE(SASPAREN);
|
PUSH_SRETRACE(SASPAREN);
|
||||||
statep->nparen = 2;
|
statep->nparen = 2;
|
||||||
|
@ -407,8 +402,8 @@ yylex(int cf)
|
||||||
memcpy(wp, sp, cz);
|
memcpy(wp, sp, cz);
|
||||||
wp += cz;
|
wp += cz;
|
||||||
}
|
}
|
||||||
} else if (c == ord('{' /*}*/)) {
|
} else if ((unsigned int)c == ORD('{' /*}*/)) {
|
||||||
if ((c = getsc()) == ord('|')) {
|
if ((unsigned int)(c = getsc()) == ORD('|')) {
|
||||||
/*
|
/*
|
||||||
* non-subenvironment
|
* non-subenvironment
|
||||||
* value substitution
|
* value substitution
|
||||||
|
@ -429,11 +424,11 @@ yylex(int cf)
|
||||||
wp = get_brace_var(&ws, wp);
|
wp = get_brace_var(&ws, wp);
|
||||||
c = getsc();
|
c = getsc();
|
||||||
/* allow :# and :% (ksh88 compat) */
|
/* allow :# and :% (ksh88 compat) */
|
||||||
if (c == ord(':')) {
|
if ((unsigned int)c == ORD(':')) {
|
||||||
*wp++ = CHAR;
|
*wp++ = CHAR;
|
||||||
*wp++ = c;
|
*wp++ = c;
|
||||||
c = getsc();
|
c = getsc();
|
||||||
if (c == ord(':')) {
|
if ((unsigned int)c == ORD(':')) {
|
||||||
*wp++ = CHAR;
|
*wp++ = CHAR;
|
||||||
*wp++ = '0';
|
*wp++ = '0';
|
||||||
*wp++ = ADELIM;
|
*wp++ = ADELIM;
|
||||||
|
@ -465,7 +460,7 @@ yylex(int cf)
|
||||||
parse_adelim_slash:
|
parse_adelim_slash:
|
||||||
*wp++ = CHAR;
|
*wp++ = CHAR;
|
||||||
*wp++ = c;
|
*wp++ = c;
|
||||||
if ((c = getsc()) == ord('/')) {
|
if ((unsigned int)(c = getsc()) == ORD('/')) {
|
||||||
*wp++ = c2;
|
*wp++ = c2;
|
||||||
*wp++ = c;
|
*wp++ = c;
|
||||||
} else
|
} else
|
||||||
|
@ -479,7 +474,7 @@ yylex(int cf)
|
||||||
} else if (c == '@') {
|
} else if (c == '@') {
|
||||||
c2 = getsc();
|
c2 = getsc();
|
||||||
ungetsc(c2);
|
ungetsc(c2);
|
||||||
if (c2 == ord('/')) {
|
if ((unsigned int)c2 == ORD('/')) {
|
||||||
c2 = CHAR;
|
c2 = CHAR;
|
||||||
goto parse_adelim_slash;
|
goto parse_adelim_slash;
|
||||||
}
|
}
|
||||||
|
@ -528,7 +523,7 @@ yylex(int cf)
|
||||||
ungetsc(c);
|
ungetsc(c);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ord('`'):
|
case ORD('`'):
|
||||||
subst_gravis:
|
subst_gravis:
|
||||||
PUSH_STATE(SBQUOTE);
|
PUSH_STATE(SBQUOTE);
|
||||||
*wp++ = COMASUB;
|
*wp++ = COMASUB;
|
||||||
|
@ -572,11 +567,11 @@ yylex(int cf)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SEQUOTE:
|
case SEQUOTE:
|
||||||
if (c == ord('\'')) {
|
if ((unsigned int)c == ORD('\'')) {
|
||||||
POP_STATE();
|
POP_STATE();
|
||||||
*wp++ = CQUOTE;
|
*wp++ = CQUOTE;
|
||||||
ignore_backslash_newline--;
|
ignore_backslash_newline--;
|
||||||
} else if (c == ord('\\')) {
|
} else if ((unsigned int)c == ORD('\\')) {
|
||||||
if ((c2 = unbksl(true, getsc_i, ungetsc)) == -1)
|
if ((c2 = unbksl(true, getsc_i, ungetsc)) == -1)
|
||||||
c2 = getsc();
|
c2 = getsc();
|
||||||
if (c2 == 0)
|
if (c2 == 0)
|
||||||
|
@ -604,7 +599,7 @@ yylex(int cf)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SSQUOTE:
|
case SSQUOTE:
|
||||||
if (c == ord('\'')) {
|
if ((unsigned int)c == ORD('\'')) {
|
||||||
POP_STATE();
|
POP_STATE();
|
||||||
if ((cf & HEREDOC) || state == SQBRACE)
|
if ((cf & HEREDOC) || state == SQBRACE)
|
||||||
goto store_char;
|
goto store_char;
|
||||||
|
@ -617,7 +612,7 @@ yylex(int cf)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SDQUOTE:
|
case SDQUOTE:
|
||||||
if (c == ord('"')) {
|
if ((unsigned int)c == ORD('"')) {
|
||||||
POP_STATE();
|
POP_STATE();
|
||||||
*wp++ = CQUOTE;
|
*wp++ = CQUOTE;
|
||||||
} else
|
} else
|
||||||
|
@ -626,15 +621,15 @@ yylex(int cf)
|
||||||
|
|
||||||
/* $(( ... )) */
|
/* $(( ... )) */
|
||||||
case SASPAREN:
|
case SASPAREN:
|
||||||
if (c == ord('('))
|
if ((unsigned int)c == ORD('('))
|
||||||
statep->nparen++;
|
statep->nparen++;
|
||||||
else if (c == ord(')')) {
|
else if ((unsigned int)c == ORD(')')) {
|
||||||
statep->nparen--;
|
statep->nparen--;
|
||||||
if (statep->nparen == 1) {
|
if (statep->nparen == 1) {
|
||||||
/* end of EXPRSUB */
|
/* end of EXPRSUB */
|
||||||
POP_SRETRACE();
|
POP_SRETRACE();
|
||||||
|
|
||||||
if ((c2 = getsc()) == ord(/*(*/ ')')) {
|
if ((unsigned int)(c2 = getsc()) == ORD(/*(*/ ')')) {
|
||||||
cz = strlen(sp) - 2;
|
cz = strlen(sp) - 2;
|
||||||
XcheckN(ws, wp, cz);
|
XcheckN(ws, wp, cz);
|
||||||
memcpy(wp, sp + 1, cz);
|
memcpy(wp, sp + 1, cz);
|
||||||
|
@ -666,7 +661,7 @@ yylex(int cf)
|
||||||
goto Sbase2;
|
goto Sbase2;
|
||||||
|
|
||||||
case SQBRACE:
|
case SQBRACE:
|
||||||
if (c == ord('\\')) {
|
if ((unsigned int)c == ORD('\\')) {
|
||||||
/*
|
/*
|
||||||
* perform POSIX "quote removal" if the back-
|
* perform POSIX "quote removal" if the back-
|
||||||
* slash is "special", i.e. same cases as the
|
* slash is "special", i.e. same cases as the
|
||||||
|
@ -675,26 +670,28 @@ yylex(int cf)
|
||||||
* write QCHAR+c, otherwise CHAR+\+CHAR+c are
|
* write QCHAR+c, otherwise CHAR+\+CHAR+c are
|
||||||
* emitted (in heredocquote:)
|
* emitted (in heredocquote:)
|
||||||
*/
|
*/
|
||||||
if ((c = getsc()) == ord('"') || c == ord('\\') ||
|
if ((unsigned int)(c = getsc()) == ORD('"') ||
|
||||||
ctype(c, C_DOLAR | C_GRAVE) || c == ord(/*{*/ '}'))
|
(unsigned int)c == ORD('\\') ||
|
||||||
|
ctype(c, C_DOLAR | C_GRAVE) ||
|
||||||
|
(unsigned int)c == ORD(/*{*/ '}'))
|
||||||
goto store_qchar;
|
goto store_qchar;
|
||||||
goto heredocquote;
|
goto heredocquote;
|
||||||
}
|
}
|
||||||
goto common_SQBRACE;
|
goto common_SQBRACE;
|
||||||
|
|
||||||
case SBRACE:
|
case SBRACE:
|
||||||
if (c == ord('\''))
|
if ((unsigned int)c == ORD('\''))
|
||||||
goto open_ssquote_unless_heredoc;
|
goto open_ssquote_unless_heredoc;
|
||||||
else if (c == ord('\\'))
|
else if ((unsigned int)c == ORD('\\'))
|
||||||
goto getsc_qchar;
|
goto getsc_qchar;
|
||||||
common_SQBRACE:
|
common_SQBRACE:
|
||||||
if (c == ord('"'))
|
if ((unsigned int)c == ORD('"'))
|
||||||
goto open_sdquote;
|
goto open_sdquote;
|
||||||
else if (c == ord('$'))
|
else if ((unsigned int)c == ORD('$'))
|
||||||
goto subst_dollar_ex;
|
goto subst_dollar_ex;
|
||||||
else if (c == ord('`'))
|
else if ((unsigned int)c == ORD('`'))
|
||||||
goto subst_gravis;
|
goto subst_gravis;
|
||||||
else if (c != ord(/*{*/ '}'))
|
else if ((unsigned int)c != ORD(/*{*/ '}'))
|
||||||
goto store_char;
|
goto store_char;
|
||||||
POP_STATE();
|
POP_STATE();
|
||||||
*wp++ = CSUBST;
|
*wp++ = CSUBST;
|
||||||
|
@ -703,16 +700,16 @@ yylex(int cf)
|
||||||
|
|
||||||
/* Same as SBASE, except (,|,) treated specially */
|
/* Same as SBASE, except (,|,) treated specially */
|
||||||
case STBRACEKORN:
|
case STBRACEKORN:
|
||||||
if (c == ord('|'))
|
if ((unsigned int)c == ORD('|'))
|
||||||
*wp++ = SPAT;
|
*wp++ = SPAT;
|
||||||
else if (c == ord('(')) {
|
else if ((unsigned int)c == ORD('(')) {
|
||||||
*wp++ = OPAT;
|
*wp++ = OPAT;
|
||||||
/* simile for @ */
|
/* simile for @ */
|
||||||
*wp++ = ' ';
|
*wp++ = ' ';
|
||||||
PUSH_STATE(SPATTERN);
|
PUSH_STATE(SPATTERN);
|
||||||
} else /* FALLTHROUGH */
|
} else /* FALLTHROUGH */
|
||||||
case STBRACEBOURNE:
|
case STBRACEBOURNE:
|
||||||
if (c == ord(/*{*/ '}')) {
|
if ((unsigned int)c == ORD(/*{*/ '}')) {
|
||||||
POP_STATE();
|
POP_STATE();
|
||||||
*wp++ = CSUBST;
|
*wp++ = CSUBST;
|
||||||
*wp++ = /*{*/ '}';
|
*wp++ = /*{*/ '}';
|
||||||
|
@ -721,20 +718,20 @@ yylex(int cf)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SBQUOTE:
|
case SBQUOTE:
|
||||||
if (c == ord('`')) {
|
if ((unsigned int)c == ORD('`')) {
|
||||||
*wp++ = 0;
|
*wp++ = 0;
|
||||||
POP_STATE();
|
POP_STATE();
|
||||||
} else if (c == ord('\\')) {
|
} else if ((unsigned int)c == ORD('\\')) {
|
||||||
switch (c = getsc()) {
|
switch (c = getsc()) {
|
||||||
case 0:
|
case 0:
|
||||||
/* trailing \ is lost */
|
/* trailing \ is lost */
|
||||||
break;
|
break;
|
||||||
case ord('$'):
|
case ORD('$'):
|
||||||
case ord('`'):
|
case ORD('`'):
|
||||||
case ord('\\'):
|
case ORD('\\'):
|
||||||
*wp++ = c;
|
*wp++ = c;
|
||||||
break;
|
break;
|
||||||
case ord('"'):
|
case ORD('"'):
|
||||||
if (statep->ls_bool) {
|
if (statep->ls_bool) {
|
||||||
*wp++ = c;
|
*wp++ = c;
|
||||||
break;
|
break;
|
||||||
|
@ -755,10 +752,10 @@ yylex(int cf)
|
||||||
|
|
||||||
/* LETEXPR: (( ... )) */
|
/* LETEXPR: (( ... )) */
|
||||||
case SLETPAREN:
|
case SLETPAREN:
|
||||||
if (c == ord(/*(*/ ')')) {
|
if ((unsigned int)c == ORD(/*(*/ ')')) {
|
||||||
if (statep->nparen > 0)
|
if (statep->nparen > 0)
|
||||||
--statep->nparen;
|
--statep->nparen;
|
||||||
else if ((c2 = getsc()) == ord(/*(*/ ')')) {
|
else if ((unsigned int)(c2 = getsc()) == ORD(/*(*/ ')')) {
|
||||||
c = 0;
|
c = 0;
|
||||||
*wp++ = CQUOTE;
|
*wp++ = CQUOTE;
|
||||||
goto Done;
|
goto Done;
|
||||||
|
@ -780,9 +777,9 @@ yylex(int cf)
|
||||||
s->next = source;
|
s->next = source;
|
||||||
source = s;
|
source = s;
|
||||||
ungetsc('(' /*)*/);
|
ungetsc('(' /*)*/);
|
||||||
return (ord('(' /*)*/));
|
return (ORD('(' /*)*/));
|
||||||
}
|
}
|
||||||
} else if (c == ord('('))
|
} else if ((unsigned int)c == ORD('('))
|
||||||
/*
|
/*
|
||||||
* parentheses inside quotes and
|
* parentheses inside quotes and
|
||||||
* backslashes are lost, but AT&T ksh
|
* backslashes are lost, but AT&T ksh
|
||||||
|
@ -798,26 +795,26 @@ yylex(int cf)
|
||||||
* $ and `...` are not to be treated specially
|
* $ and `...` are not to be treated specially
|
||||||
*/
|
*/
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case ord('\\'):
|
case ORD('\\'):
|
||||||
if ((c = getsc())) {
|
if ((c = getsc())) {
|
||||||
/* trailing \ is lost */
|
/* trailing \ is lost */
|
||||||
*wp++ = QCHAR;
|
*wp++ = QCHAR;
|
||||||
*wp++ = c;
|
*wp++ = c;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ord('\''):
|
case ORD('\''):
|
||||||
goto open_ssquote_unless_heredoc;
|
goto open_ssquote_unless_heredoc;
|
||||||
case ord('$'):
|
case ORD('$'):
|
||||||
if ((c2 = getsc()) == ord('\'')) {
|
if ((unsigned int)(c2 = getsc()) == ORD('\'')) {
|
||||||
open_sequote:
|
open_sequote:
|
||||||
*wp++ = OQUOTE;
|
*wp++ = OQUOTE;
|
||||||
ignore_backslash_newline++;
|
ignore_backslash_newline++;
|
||||||
PUSH_STATE(SEQUOTE);
|
PUSH_STATE(SEQUOTE);
|
||||||
statep->ls_bool = false;
|
statep->ls_bool = false;
|
||||||
break;
|
break;
|
||||||
} else if (c2 == ord('"')) {
|
} else if ((unsigned int)c2 == ORD('"')) {
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case ord('"'):
|
case ORD('"'):
|
||||||
PUSH_SRETRACE(SHEREDQUOTE);
|
PUSH_SRETRACE(SHEREDQUOTE);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -831,7 +828,7 @@ yylex(int cf)
|
||||||
|
|
||||||
/* " in << or <<- delimiter */
|
/* " in << or <<- delimiter */
|
||||||
case SHEREDQUOTE:
|
case SHEREDQUOTE:
|
||||||
if (c != ord('"'))
|
if ((unsigned int)c != ORD('"'))
|
||||||
goto Subst;
|
goto Subst;
|
||||||
POP_SRETRACE();
|
POP_SRETRACE();
|
||||||
dp = strnul(sp) - 1;
|
dp = strnul(sp) - 1;
|
||||||
|
@ -844,10 +841,10 @@ yylex(int cf)
|
||||||
while ((c = *dp++)) {
|
while ((c = *dp++)) {
|
||||||
if (c == '\\') {
|
if (c == '\\') {
|
||||||
switch ((c = *dp++)) {
|
switch ((c = *dp++)) {
|
||||||
case ord('\\'):
|
case ORD('\\'):
|
||||||
case ord('"'):
|
case ORD('"'):
|
||||||
case ord('$'):
|
case ORD('$'):
|
||||||
case ord('`'):
|
case ORD('`'):
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
*wp++ = CHAR;
|
*wp++ = CHAR;
|
||||||
|
@ -865,12 +862,12 @@ yylex(int cf)
|
||||||
|
|
||||||
/* in *(...|...) pattern (*+?@!) */
|
/* in *(...|...) pattern (*+?@!) */
|
||||||
case SPATTERN:
|
case SPATTERN:
|
||||||
if (c == ord(/*(*/ ')')) {
|
if ((unsigned int)c == ORD(/*(*/ ')')) {
|
||||||
*wp++ = CPAT;
|
*wp++ = CPAT;
|
||||||
POP_STATE();
|
POP_STATE();
|
||||||
} else if (c == ord('|')) {
|
} else if ((unsigned int)c == ORD('|')) {
|
||||||
*wp++ = SPAT;
|
*wp++ = SPAT;
|
||||||
} else if (c == ord('(')) {
|
} else if ((unsigned int)c == ORD('(')) {
|
||||||
*wp++ = OPAT;
|
*wp++ = OPAT;
|
||||||
/* simile for @ */
|
/* simile for @ */
|
||||||
*wp++ = ' ';
|
*wp++ = ' ';
|
||||||
|
@ -900,7 +897,7 @@ yylex(int cf)
|
||||||
iop->unit = c2 == 2 ? ksh_numdig(dp[1]) : c == '<' ? 0 : 1;
|
iop->unit = c2 == 2 ? ksh_numdig(dp[1]) : c == '<' ? 0 : 1;
|
||||||
|
|
||||||
if (c == '&') {
|
if (c == '&') {
|
||||||
if ((c2 = getsc()) != ord('>')) {
|
if ((unsigned int)(c2 = getsc()) != ORD('>')) {
|
||||||
ungetsc(c2);
|
ungetsc(c2);
|
||||||
goto no_iop;
|
goto no_iop;
|
||||||
}
|
}
|
||||||
|
@ -911,22 +908,23 @@ yylex(int cf)
|
||||||
|
|
||||||
c2 = getsc();
|
c2 = getsc();
|
||||||
/* <<, >>, <> are ok, >< is not */
|
/* <<, >>, <> are ok, >< is not */
|
||||||
if (c == c2 || (c == ord('<') && c2 == ord('>'))) {
|
if (c == c2 || ((unsigned int)c == ORD('<') &&
|
||||||
|
(unsigned int)c2 == ORD('>'))) {
|
||||||
iop->ioflag |= c == c2 ?
|
iop->ioflag |= c == c2 ?
|
||||||
(c == ord('>') ? IOCAT : IOHERE) : IORDWR;
|
((unsigned int)c == ORD('>') ? IOCAT : IOHERE) : IORDWR;
|
||||||
if (iop->ioflag == IOHERE) {
|
if (iop->ioflag == IOHERE) {
|
||||||
if ((c2 = getsc()) == ord('-'))
|
if ((unsigned int)(c2 = getsc()) == ORD('-'))
|
||||||
iop->ioflag |= IOSKIP;
|
iop->ioflag |= IOSKIP;
|
||||||
else if (c2 == ord('<'))
|
else if ((unsigned int)c2 == ORD('<'))
|
||||||
iop->ioflag |= IOHERESTR;
|
iop->ioflag |= IOHERESTR;
|
||||||
else
|
else
|
||||||
ungetsc(c2);
|
ungetsc(c2);
|
||||||
}
|
}
|
||||||
} else if (c2 == ord('&'))
|
} else if ((unsigned int)c2 == ORD('&'))
|
||||||
iop->ioflag |= IODUP | (c == ord('<') ? IORDUP : 0);
|
iop->ioflag |= IODUP | ((unsigned int)c == ORD('<') ? IORDUP : 0);
|
||||||
else {
|
else {
|
||||||
iop->ioflag |= c == ord('>') ? IOWRITE : IOREAD;
|
iop->ioflag |= (unsigned int)c == ORD('>') ? IOWRITE : IOREAD;
|
||||||
if (c == ord('>') && c2 == ord('|'))
|
if ((unsigned int)c == ORD('>') && (unsigned int)c2 == ORD('|'))
|
||||||
iop->ioflag |= IOCLOB;
|
iop->ioflag |= IOCLOB;
|
||||||
else
|
else
|
||||||
ungetsc(c2);
|
ungetsc(c2);
|
||||||
|
@ -947,30 +945,32 @@ yylex(int cf)
|
||||||
/* free word */
|
/* free word */
|
||||||
Xfree(ws, wp);
|
Xfree(ws, wp);
|
||||||
/* no word, process LEX1 character */
|
/* no word, process LEX1 character */
|
||||||
if ((c == ord('|')) || (c == ord('&')) || (c == ord(';')) ||
|
if (((unsigned int)c == ORD('|')) ||
|
||||||
(c == ord('(' /*)*/))) {
|
((unsigned int)c == ORD('&')) ||
|
||||||
|
((unsigned int)c == ORD(';')) ||
|
||||||
|
((unsigned int)c == ORD('(' /*)*/))) {
|
||||||
if ((c2 = getsc()) == c)
|
if ((c2 = getsc()) == c)
|
||||||
c = (c == ord(';')) ? BREAK :
|
c = ((unsigned int)c == ORD(';')) ? BREAK :
|
||||||
(c == ord('|')) ? LOGOR :
|
((unsigned int)c == ORD('|')) ? LOGOR :
|
||||||
(c == ord('&')) ? LOGAND :
|
((unsigned int)c == ORD('&')) ? LOGAND :
|
||||||
/* c == ord('(' )) */ MDPAREN;
|
/* (unsigned int)c == ORD('(' )) */ MDPAREN;
|
||||||
else if (c == ord('|') && c2 == ord('&'))
|
else if ((unsigned int)c == ORD('|') && (unsigned int)c2 == ORD('&'))
|
||||||
c = COPROC;
|
c = COPROC;
|
||||||
else if (c == ord(';') && c2 == ord('|'))
|
else if ((unsigned int)c == ORD(';') && (unsigned int)c2 == ORD('|'))
|
||||||
c = BRKEV;
|
c = BRKEV;
|
||||||
else if (c == ord(';') && c2 == ord('&'))
|
else if ((unsigned int)c == ORD(';') && (unsigned int)c2 == ORD('&'))
|
||||||
c = BRKFT;
|
c = BRKFT;
|
||||||
else
|
else
|
||||||
ungetsc(c2);
|
ungetsc(c2);
|
||||||
#ifndef MKSH_SMALL
|
#ifndef MKSH_SMALL
|
||||||
if (c == BREAK) {
|
if (c == BREAK) {
|
||||||
if ((c2 = getsc()) == ord('&'))
|
if ((unsigned int)(c2 = getsc()) == ORD('&'))
|
||||||
c = BRKEV;
|
c = BRKEV;
|
||||||
else
|
else
|
||||||
ungetsc(c2);
|
ungetsc(c2);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
} else if (c == ord('\n')) {
|
} else if ((unsigned int)c == ORD('\n')) {
|
||||||
if (cf & HEREDELIM)
|
if (cf & HEREDELIM)
|
||||||
ungetsc(c);
|
ungetsc(c);
|
||||||
else {
|
else {
|
||||||
|
@ -1025,7 +1025,7 @@ yylex(int cf)
|
||||||
|
|
||||||
if ((cf & KEYWORD) && (p = ktsearch(&keywords, ident, h)) &&
|
if ((cf & KEYWORD) && (p = ktsearch(&keywords, ident, h)) &&
|
||||||
(!(cf & ESACONLY) || p->val.i == ESAC ||
|
(!(cf & ESACONLY) || p->val.i == ESAC ||
|
||||||
p->val.i == ord(/*{*/ '}'))) {
|
(unsigned int)p->val.i == ORD(/*{*/ '}'))) {
|
||||||
afree(yylval.cp, ATEMP);
|
afree(yylval.cp, ATEMP);
|
||||||
return (p->val.i);
|
return (p->val.i);
|
||||||
}
|
}
|
||||||
|
@ -1136,7 +1136,7 @@ readhere(struct ioword *iop)
|
||||||
if (!*eofp) {
|
if (!*eofp) {
|
||||||
/* end of here document marker, what to do? */
|
/* end of here document marker, what to do? */
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case ord(/*(*/ ')'):
|
case ORD(/*(*/ ')'):
|
||||||
if (!subshell_nesting_type)
|
if (!subshell_nesting_type)
|
||||||
/*-
|
/*-
|
||||||
* not allowed outside $(...) or (...)
|
* not allowed outside $(...) or (...)
|
||||||
|
@ -1151,7 +1151,7 @@ readhere(struct ioword *iop)
|
||||||
* Allow EOF here to commands without trailing
|
* Allow EOF here to commands without trailing
|
||||||
* newlines (mksh -c '...') will work as well.
|
* newlines (mksh -c '...') will work as well.
|
||||||
*/
|
*/
|
||||||
case ord('\n'):
|
case ORD('\n'):
|
||||||
/* Newline terminates here document marker */
|
/* Newline terminates here document marker */
|
||||||
goto heredoc_found_terminator;
|
goto heredoc_found_terminator;
|
||||||
}
|
}
|
||||||
|
@ -1580,7 +1580,7 @@ get_brace_var(XString *wsp, char *wp)
|
||||||
|
|
||||||
c2 = getsc();
|
c2 = getsc();
|
||||||
ungetsc(c2);
|
ungetsc(c2);
|
||||||
if (ord(c2) != ord(/*{*/ '}')) {
|
if (ord(c2) != ORD(/*{*/ '}')) {
|
||||||
ungetsc(c);
|
ungetsc(c);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -1588,22 +1588,22 @@ get_brace_var(XString *wsp, char *wp)
|
||||||
goto ps_common;
|
goto ps_common;
|
||||||
case PS_SAW_BANG:
|
case PS_SAW_BANG:
|
||||||
switch (ord(c)) {
|
switch (ord(c)) {
|
||||||
case ord('@'):
|
case ORD('@'):
|
||||||
case ord('#'):
|
case ORD('#'):
|
||||||
case ord('-'):
|
case ORD('-'):
|
||||||
case ord('?'):
|
case ORD('?'):
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
goto ps_common;
|
goto ps_common;
|
||||||
case PS_INITIAL:
|
case PS_INITIAL:
|
||||||
switch (ord(c)) {
|
switch (ord(c)) {
|
||||||
case ord('%'):
|
case ORD('%'):
|
||||||
state = PS_SAW_PERCENT;
|
state = PS_SAW_PERCENT;
|
||||||
goto next;
|
goto next;
|
||||||
case ord('#'):
|
case ORD('#'):
|
||||||
state = PS_SAW_HASH;
|
state = PS_SAW_HASH;
|
||||||
goto next;
|
goto next;
|
||||||
case ord('!'):
|
case ORD('!'):
|
||||||
state = PS_SAW_BANG;
|
state = PS_SAW_BANG;
|
||||||
goto next;
|
goto next;
|
||||||
}
|
}
|
||||||
|
@ -1621,7 +1621,7 @@ get_brace_var(XString *wsp, char *wp)
|
||||||
break;
|
break;
|
||||||
case PS_IDENT:
|
case PS_IDENT:
|
||||||
if (!ctype(c, C_ALNUX)) {
|
if (!ctype(c, C_ALNUX)) {
|
||||||
if (ord(c) == ord('[')) {
|
if (ord(c) == ORD('[')) {
|
||||||
char *tmp, *p;
|
char *tmp, *p;
|
||||||
|
|
||||||
if (!arraysub(&tmp))
|
if (!arraysub(&tmp))
|
||||||
|
@ -1676,9 +1676,9 @@ arraysub(char **strp)
|
||||||
c = getsc();
|
c = getsc();
|
||||||
Xcheck(ws, wp);
|
Xcheck(ws, wp);
|
||||||
*wp++ = c;
|
*wp++ = c;
|
||||||
if (ord(c) == ord('['))
|
if (ord(c) == ORD('['))
|
||||||
depth++;
|
depth++;
|
||||||
else if (ord(c) == ord(']'))
|
else if (ord(c) == ORD(']'))
|
||||||
depth--;
|
depth--;
|
||||||
} while (depth > 0 && c && c != '\n');
|
} while (depth > 0 && c && c != '\n');
|
||||||
|
|
||||||
|
|
131
src/main.c
131
src/main.c
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
|
* Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
|
||||||
* 2011, 2012, 2013, 2014, 2015, 2016, 2017
|
* 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018
|
||||||
* mirabilos <m@mirbsd.org>
|
* mirabilos <m@mirbsd.org>
|
||||||
*
|
*
|
||||||
* Provided that these terms and disclaimer and all copyright notices
|
* Provided that these terms and disclaimer and all copyright notices
|
||||||
|
@ -34,9 +34,7 @@
|
||||||
#include <locale.h>
|
#include <locale.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
__RCSID("$MirOS: src/bin/mksh/main.c,v 1.342 2017/04/28 11:13:47 tg Exp $");
|
__RCSID("$MirOS: src/bin/mksh/main.c,v 1.347 2018/01/13 21:45:07 tg Exp $");
|
||||||
|
|
||||||
extern char **environ;
|
|
||||||
|
|
||||||
#ifndef MKSHRC_PATH
|
#ifndef MKSHRC_PATH
|
||||||
#define MKSHRC_PATH "~/.mkshrc"
|
#define MKSHRC_PATH "~/.mkshrc"
|
||||||
|
@ -52,6 +50,7 @@ void chvt_reinit(void);
|
||||||
static void reclaim(void);
|
static void reclaim(void);
|
||||||
static void remove_temps(struct temp *);
|
static void remove_temps(struct temp *);
|
||||||
static mksh_uari_t rndsetup(void);
|
static mksh_uari_t rndsetup(void);
|
||||||
|
static void init_environ(void);
|
||||||
#ifdef SIGWINCH
|
#ifdef SIGWINCH
|
||||||
static void x_sigwinch(int);
|
static void x_sigwinch(int);
|
||||||
#endif
|
#endif
|
||||||
|
@ -242,10 +241,6 @@ main_init(int argc, const char *argv[], Source **sp, struct block **lp)
|
||||||
set_ifs(TC_IFSWS);
|
set_ifs(TC_IFSWS);
|
||||||
|
|
||||||
#ifdef __OS2__
|
#ifdef __OS2__
|
||||||
for (i = 0; i < 3; ++i)
|
|
||||||
if (!isatty(i))
|
|
||||||
setmode(i, O_BINARY);
|
|
||||||
|
|
||||||
os2_init(&argc, &argv);
|
os2_init(&argc, &argv);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -401,14 +396,7 @@ main_init(int argc, const char *argv[], Source **sp, struct block **lp)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* import environment */
|
/* import environment */
|
||||||
if (environ != NULL) {
|
init_environ();
|
||||||
wp = (const char **)environ;
|
|
||||||
while (*wp != NULL) {
|
|
||||||
rndpush(*wp);
|
|
||||||
typeset(*wp, IMPORT | EXPORT, 0, 0, 0);
|
|
||||||
++wp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* override default PATH regardless of environment */
|
/* override default PATH regardless of environment */
|
||||||
#ifdef MKSH_DEFPATH_OVERRIDE
|
#ifdef MKSH_DEFPATH_OVERRIDE
|
||||||
|
@ -671,8 +659,7 @@ main_init(int argc, const char *argv[], Source **sp, struct block **lp)
|
||||||
if (Flag(FLOGIN))
|
if (Flag(FLOGIN))
|
||||||
include(substitute("$HOME/.profile", 0), 0, NULL, true);
|
include(substitute("$HOME/.profile", 0), 0, NULL, true);
|
||||||
if (Flag(FTALKING)) {
|
if (Flag(FTALKING)) {
|
||||||
cp = substitute(substitute("${ENV:-" MKSHRC_PATH "}",
|
cp = substitute("${ENV:-" MKSHRC_PATH "}", DOTILDE);
|
||||||
0), DOTILDE);
|
|
||||||
if (cp[0] != '\0')
|
if (cp[0] != '\0')
|
||||||
include(cp, 0, NULL, true);
|
include(cp, 0, NULL, true);
|
||||||
}
|
}
|
||||||
|
@ -1987,3 +1974,111 @@ x_mkraw(int fd, mksh_ttyst *ocb, bool forread)
|
||||||
|
|
||||||
mksh_tcset(fd, &cb);
|
mksh_tcset(fd, &cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MKSH_ENVDIR
|
||||||
|
static void
|
||||||
|
init_environ(void)
|
||||||
|
{
|
||||||
|
char *xp;
|
||||||
|
ssize_t n;
|
||||||
|
XString xs;
|
||||||
|
struct shf *shf;
|
||||||
|
DIR *dirp;
|
||||||
|
struct dirent *dent;
|
||||||
|
|
||||||
|
if ((dirp = opendir(MKSH_ENVDIR)) == NULL) {
|
||||||
|
warningf(false, "cannot read environment from %s: %s",
|
||||||
|
MKSH_ENVDIR, cstrerror(errno));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
XinitN(xs, 256, ATEMP);
|
||||||
|
read_envfile:
|
||||||
|
errno = 0;
|
||||||
|
if ((dent = readdir(dirp)) != NULL) {
|
||||||
|
if (skip_varname(dent->d_name, true)[0] == '\0') {
|
||||||
|
xp = shf_smprintf(Tf_sSs, MKSH_ENVDIR, dent->d_name);
|
||||||
|
if (!(shf = shf_open(xp, O_RDONLY, 0, 0))) {
|
||||||
|
warningf(false,
|
||||||
|
"cannot read environment %s from %s: %s",
|
||||||
|
dent->d_name, MKSH_ENVDIR,
|
||||||
|
cstrerror(errno));
|
||||||
|
goto read_envfile;
|
||||||
|
}
|
||||||
|
afree(xp, ATEMP);
|
||||||
|
n = strlen(dent->d_name);
|
||||||
|
xp = Xstring(xs, xp);
|
||||||
|
XcheckN(xs, xp, n + 32);
|
||||||
|
memcpy(xp, dent->d_name, n);
|
||||||
|
xp += n;
|
||||||
|
*xp++ = '=';
|
||||||
|
while ((n = shf_read(xp, Xnleft(xs, xp), shf)) > 0) {
|
||||||
|
xp += n;
|
||||||
|
if (Xnleft(xs, xp) <= 0)
|
||||||
|
XcheckN(xs, xp, Xlength(xs, xp));
|
||||||
|
}
|
||||||
|
if (n < 0) {
|
||||||
|
warningf(false,
|
||||||
|
"cannot read environment %s from %s: %s",
|
||||||
|
dent->d_name, MKSH_ENVDIR,
|
||||||
|
cstrerror(shf_errno(shf)));
|
||||||
|
} else {
|
||||||
|
*xp = '\0';
|
||||||
|
xp = Xstring(xs, xp);
|
||||||
|
rndpush(xp);
|
||||||
|
typeset(xp, IMPORT | EXPORT, 0, 0, 0);
|
||||||
|
}
|
||||||
|
shf_close(shf);
|
||||||
|
}
|
||||||
|
goto read_envfile;
|
||||||
|
} else if (errno)
|
||||||
|
warningf(false, "cannot read environment from %s: %s",
|
||||||
|
MKSH_ENVDIR, cstrerror(errno));
|
||||||
|
closedir(dirp);
|
||||||
|
Xfree(xs, xp);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
extern char **environ;
|
||||||
|
|
||||||
|
static void
|
||||||
|
init_environ(void)
|
||||||
|
{
|
||||||
|
const char **wp;
|
||||||
|
|
||||||
|
if (environ == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
wp = (const char **)environ;
|
||||||
|
while (*wp != NULL) {
|
||||||
|
rndpush(*wp);
|
||||||
|
typeset(*wp, IMPORT | EXPORT, 0, 0, 0);
|
||||||
|
++wp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef MKSH_EARLY_LOCALE_TRACKING
|
||||||
|
void
|
||||||
|
recheck_ctype(void)
|
||||||
|
{
|
||||||
|
const char *ccp;
|
||||||
|
|
||||||
|
ccp = str_val(global("LC_ALL"));
|
||||||
|
if (ccp == null)
|
||||||
|
ccp = str_val(global("LC_CTYPE"));
|
||||||
|
if (ccp == null)
|
||||||
|
ccp = str_val(global("LANG"));
|
||||||
|
UTFMODE = isuc(ccp);
|
||||||
|
#if HAVE_SETLOCALE_CTYPE
|
||||||
|
ccp = setlocale(LC_CTYPE, ccp);
|
||||||
|
#if HAVE_LANGINFO_CODESET
|
||||||
|
if (!isuc(ccp))
|
||||||
|
ccp = nl_langinfo(CODESET);
|
||||||
|
#endif
|
||||||
|
if (isuc(ccp))
|
||||||
|
UTFMODE = 1;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (Flag(FPOSIX))
|
||||||
|
warningf(true, "early locale tracking enabled UTF-8 mode while in POSIX mode, you are now noncompliant");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
177
src/misc.c
177
src/misc.c
|
@ -32,7 +32,7 @@
|
||||||
#include <grp.h>
|
#include <grp.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
__RCSID("$MirOS: src/bin/mksh/misc.c,v 1.279 2017/08/07 21:39:25 tg Exp $");
|
__RCSID("$MirOS: src/bin/mksh/misc.c,v 1.291 2018/01/14 00:03:03 tg Exp $");
|
||||||
|
|
||||||
#define KSH_CHVT_FLAG
|
#define KSH_CHVT_FLAG
|
||||||
#ifdef MKSH_SMALL
|
#ifdef MKSH_SMALL
|
||||||
|
@ -696,14 +696,14 @@ has_globbing(const char *pat)
|
||||||
if (!(c = *p++))
|
if (!(c = *p++))
|
||||||
return (false);
|
return (false);
|
||||||
/* some specials */
|
/* some specials */
|
||||||
if (ord(c) == ord('*') || ord(c) == ord('?')) {
|
if (ord(c) == ORD('*') || ord(c) == ORD('?')) {
|
||||||
/* easy glob, accept */
|
/* easy glob, accept */
|
||||||
saw_glob = true;
|
saw_glob = true;
|
||||||
} else if (ord(c) == ord('[')) {
|
} else if (ord(c) == ORD('[')) {
|
||||||
/* bracket expression; eat negation and initial ] */
|
/* bracket expression; eat negation and initial ] */
|
||||||
if (ISMAGIC(p[0]) && ord(p[1]) == ord('!'))
|
if (ISMAGIC(p[0]) && ord(p[1]) == ORD('!'))
|
||||||
p += 2;
|
p += 2;
|
||||||
if (ISMAGIC(p[0]) && ord(p[1]) == ord(']'))
|
if (ISMAGIC(p[0]) && ord(p[1]) == ORD(']'))
|
||||||
p += 2;
|
p += 2;
|
||||||
/* check next string part */
|
/* check next string part */
|
||||||
s = p;
|
s = p;
|
||||||
|
@ -715,27 +715,27 @@ has_globbing(const char *pat)
|
||||||
if (!(c = *s++))
|
if (!(c = *s++))
|
||||||
return (false);
|
return (false);
|
||||||
/* terminating bracket? */
|
/* terminating bracket? */
|
||||||
if (ord(c) == ord(']')) {
|
if (ord(c) == ORD(']')) {
|
||||||
/* accept and continue */
|
/* accept and continue */
|
||||||
p = s;
|
p = s;
|
||||||
saw_glob = true;
|
saw_glob = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* sub-bracket expressions */
|
/* sub-bracket expressions */
|
||||||
if (ord(c) == ord('[') && (
|
if (ord(c) == ORD('[') && (
|
||||||
/* collating element? */
|
/* collating element? */
|
||||||
ord(*s) == ord('.') ||
|
ord(*s) == ORD('.') ||
|
||||||
/* equivalence class? */
|
/* equivalence class? */
|
||||||
ord(*s) == ord('=') ||
|
ord(*s) == ORD('=') ||
|
||||||
/* character class? */
|
/* character class? */
|
||||||
ord(*s) == ord(':'))) {
|
ord(*s) == ORD(':'))) {
|
||||||
/* must stop with exactly the same c */
|
/* must stop with exactly the same c */
|
||||||
subc = *s++;
|
subc = *s++;
|
||||||
/* arbitrarily many chars in betwixt */
|
/* arbitrarily many chars in betwixt */
|
||||||
while ((c = *s++))
|
while ((c = *s++))
|
||||||
/* but only this sequence... */
|
/* but only this sequence... */
|
||||||
if (c == subc && ISMAGIC(*s) &&
|
if (c == subc && ISMAGIC(*s) &&
|
||||||
ord(s[1]) == ord(']')) {
|
ord(s[1]) == ORD(']')) {
|
||||||
/* accept, terminate */
|
/* accept, terminate */
|
||||||
s += 2;
|
s += 2;
|
||||||
break;
|
break;
|
||||||
|
@ -751,7 +751,7 @@ has_globbing(const char *pat)
|
||||||
/* opening pattern */
|
/* opening pattern */
|
||||||
saw_glob = true;
|
saw_glob = true;
|
||||||
++nest;
|
++nest;
|
||||||
} else if (ord(c) == ord(/*(*/ ')')) {
|
} else if (ord(c) == ORD(/*(*/ ')')) {
|
||||||
/* closing pattern */
|
/* closing pattern */
|
||||||
if (nest)
|
if (nest)
|
||||||
--nest;
|
--nest;
|
||||||
|
@ -785,24 +785,24 @@ do_gmatch(const unsigned char *s, const unsigned char *se,
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
switch (ord(*p++)) {
|
switch (ord(*p++)) {
|
||||||
case ord('['):
|
case ORD('['):
|
||||||
/* BSD cclass extension? */
|
/* BSD cclass extension? */
|
||||||
if (ISMAGIC(p[0]) && ord(p[1]) == ord('[') &&
|
if (ISMAGIC(p[0]) && ord(p[1]) == ORD('[') &&
|
||||||
ord(p[2]) == ord(':') &&
|
ord(p[2]) == ORD(':') &&
|
||||||
ctype((pc = p[3]), C_ANGLE) &&
|
ctype((pc = p[3]), C_ANGLE) &&
|
||||||
ord(p[4]) == ord(':') &&
|
ord(p[4]) == ORD(':') &&
|
||||||
ISMAGIC(p[5]) && ord(p[6]) == ord(']') &&
|
ISMAGIC(p[5]) && ord(p[6]) == ORD(']') &&
|
||||||
ISMAGIC(p[7]) && ord(p[8]) == ord(']')) {
|
ISMAGIC(p[7]) && ord(p[8]) == ORD(']')) {
|
||||||
/* zero-length match */
|
/* zero-length match */
|
||||||
--s;
|
--s;
|
||||||
p += 9;
|
p += 9;
|
||||||
/* word begin? */
|
/* word begin? */
|
||||||
if (ord(pc) == ord('<') &&
|
if (ord(pc) == ORD('<') &&
|
||||||
!ctype(sl, C_ALNUX) &&
|
!ctype(sl, C_ALNUX) &&
|
||||||
ctype(sc, C_ALNUX))
|
ctype(sc, C_ALNUX))
|
||||||
break;
|
break;
|
||||||
/* word end? */
|
/* word end? */
|
||||||
if (ord(pc) == ord('>') &&
|
if (ord(pc) == ORD('>') &&
|
||||||
ctype(sl, C_ALNUX) &&
|
ctype(sl, C_ALNUX) &&
|
||||||
!ctype(sc, C_ALNUX))
|
!ctype(sc, C_ALNUX))
|
||||||
break;
|
break;
|
||||||
|
@ -813,7 +813,7 @@ do_gmatch(const unsigned char *s, const unsigned char *se,
|
||||||
return (0);
|
return (0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ord('?'):
|
case ORD('?'):
|
||||||
if (sc == 0)
|
if (sc == 0)
|
||||||
return (0);
|
return (0);
|
||||||
if (UTFMODE) {
|
if (UTFMODE) {
|
||||||
|
@ -822,7 +822,7 @@ do_gmatch(const unsigned char *s, const unsigned char *se,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ord('*'):
|
case ORD('*'):
|
||||||
if (p == pe)
|
if (p == pe)
|
||||||
return (1);
|
return (1);
|
||||||
s--;
|
s--;
|
||||||
|
@ -838,14 +838,14 @@ do_gmatch(const unsigned char *s, const unsigned char *se,
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* matches one or more times */
|
/* matches one or more times */
|
||||||
case 0x80|ord('+'):
|
case ORD('+') | 0x80:
|
||||||
/* matches zero or more times */
|
/* matches zero or more times */
|
||||||
case 0x80|ord('*'):
|
case ORD('*') | 0x80:
|
||||||
if (!(prest = pat_scan(p, pe, false)))
|
if (!(prest = pat_scan(p, pe, false)))
|
||||||
return (0);
|
return (0);
|
||||||
s--;
|
s--;
|
||||||
/* take care of zero matches */
|
/* take care of zero matches */
|
||||||
if (ord(p[-1]) == (0x80 | ord('*')) &&
|
if (ord(p[-1]) == (0x80 | ORD('*')) &&
|
||||||
do_gmatch(s, se, prest, pe, smin))
|
do_gmatch(s, se, prest, pe, smin))
|
||||||
return (1);
|
return (1);
|
||||||
for (psub = p; ; psub = pnext) {
|
for (psub = p; ; psub = pnext) {
|
||||||
|
@ -863,16 +863,16 @@ do_gmatch(const unsigned char *s, const unsigned char *se,
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
/* matches zero or once */
|
/* matches zero or once */
|
||||||
case 0x80|ord('?'):
|
case ORD('?') | 0x80:
|
||||||
/* matches one of the patterns */
|
/* matches one of the patterns */
|
||||||
case 0x80|ord('@'):
|
case ORD('@') | 0x80:
|
||||||
/* simile for @ */
|
/* simile for @ */
|
||||||
case 0x80|ord(' '):
|
case ORD(' ') | 0x80:
|
||||||
if (!(prest = pat_scan(p, pe, false)))
|
if (!(prest = pat_scan(p, pe, false)))
|
||||||
return (0);
|
return (0);
|
||||||
s--;
|
s--;
|
||||||
/* Take care of zero matches */
|
/* Take care of zero matches */
|
||||||
if (ord(p[-1]) == (0x80 | ord('?')) &&
|
if (ord(p[-1]) == (0x80 | ORD('?')) &&
|
||||||
do_gmatch(s, se, prest, pe, smin))
|
do_gmatch(s, se, prest, pe, smin))
|
||||||
return (1);
|
return (1);
|
||||||
for (psub = p; ; psub = pnext) {
|
for (psub = p; ; psub = pnext) {
|
||||||
|
@ -889,7 +889,7 @@ do_gmatch(const unsigned char *s, const unsigned char *se,
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
/* matches none of the patterns */
|
/* matches none of the patterns */
|
||||||
case 0x80|ord('!'):
|
case ORD('!') | 0x80:
|
||||||
if (!(prest = pat_scan(p, pe, false)))
|
if (!(prest = pat_scan(p, pe, false)))
|
||||||
return (0);
|
return (0);
|
||||||
s--;
|
s--;
|
||||||
|
@ -966,12 +966,12 @@ gmatch_cclass(const unsigned char *pat, unsigned char sc)
|
||||||
char *subp;
|
char *subp;
|
||||||
|
|
||||||
/* check for negation */
|
/* check for negation */
|
||||||
if (ISMAGIC(p[0]) && ord(p[1]) == ord('!')) {
|
if (ISMAGIC(p[0]) && ord(p[1]) == ORD('!')) {
|
||||||
p += 2;
|
p += 2;
|
||||||
negated = true;
|
negated = true;
|
||||||
}
|
}
|
||||||
/* make initial ] non-MAGIC */
|
/* make initial ] non-MAGIC */
|
||||||
if (ISMAGIC(p[0]) && ord(p[1]) == ord(']'))
|
if (ISMAGIC(p[0]) && ord(p[1]) == ORD(']'))
|
||||||
++p;
|
++p;
|
||||||
/* iterate over bracket expression, debunk()ing on the fly */
|
/* iterate over bracket expression, debunk()ing on the fly */
|
||||||
while ((c = *p++)) {
|
while ((c = *p++)) {
|
||||||
|
@ -982,18 +982,18 @@ gmatch_cclass(const unsigned char *pat, unsigned char sc)
|
||||||
if (!(c = *p++))
|
if (!(c = *p++))
|
||||||
break;
|
break;
|
||||||
/* terminating bracket? */
|
/* terminating bracket? */
|
||||||
if (ord(c) == ord(']')) {
|
if (ord(c) == ORD(']')) {
|
||||||
/* accept and return */
|
/* accept and return */
|
||||||
return (found != negated ? p : NULL);
|
return (found != negated ? p : NULL);
|
||||||
}
|
}
|
||||||
/* sub-bracket expressions */
|
/* sub-bracket expressions */
|
||||||
if (ord(c) == ord('[') && (
|
if (ord(c) == ORD('[') && (
|
||||||
/* collating element? */
|
/* collating element? */
|
||||||
ord(*p) == ord('.') ||
|
ord(*p) == ORD('.') ||
|
||||||
/* equivalence class? */
|
/* equivalence class? */
|
||||||
ord(*p) == ord('=') ||
|
ord(*p) == ORD('=') ||
|
||||||
/* character class? */
|
/* character class? */
|
||||||
ord(*p) == ord(':'))) {
|
ord(*p) == ORD(':'))) {
|
||||||
/* must stop with exactly the same c */
|
/* must stop with exactly the same c */
|
||||||
subc = *p++;
|
subc = *p++;
|
||||||
/* save away start of substring */
|
/* save away start of substring */
|
||||||
|
@ -1002,7 +1002,7 @@ gmatch_cclass(const unsigned char *pat, unsigned char sc)
|
||||||
while ((c = *p++))
|
while ((c = *p++))
|
||||||
/* but only this sequence... */
|
/* but only this sequence... */
|
||||||
if (c == subc && ISMAGIC(*p) &&
|
if (c == subc && ISMAGIC(*p) &&
|
||||||
ord(p[1]) == ord(']')) {
|
ord(p[1]) == ORD(']')) {
|
||||||
/* accept, terminate */
|
/* accept, terminate */
|
||||||
p += 2;
|
p += 2;
|
||||||
break;
|
break;
|
||||||
|
@ -1015,7 +1015,7 @@ gmatch_cclass(const unsigned char *pat, unsigned char sc)
|
||||||
debunk(subp, subp, p - s - 3 + 1);
|
debunk(subp, subp, p - s - 3 + 1);
|
||||||
cclass_common:
|
cclass_common:
|
||||||
/* whither subexpression */
|
/* whither subexpression */
|
||||||
if (ord(subc) == ord(':')) {
|
if (ord(subc) == ORD(':')) {
|
||||||
const struct cclass *cls = cclasses;
|
const struct cclass *cls = cclasses;
|
||||||
|
|
||||||
/* search for name in cclass list */
|
/* search for name in cclass list */
|
||||||
|
@ -1055,9 +1055,9 @@ gmatch_cclass(const unsigned char *pat, unsigned char sc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* range expression? */
|
/* range expression? */
|
||||||
if (!(ISMAGIC(p[0]) && ord(p[1]) == ord('-') &&
|
if (!(ISMAGIC(p[0]) && ord(p[1]) == ORD('-') &&
|
||||||
/* not terminating bracket? */
|
/* not terminating bracket? */
|
||||||
(!ISMAGIC(p[2]) || ord(p[3]) != ord(']')))) {
|
(!ISMAGIC(p[2]) || ord(p[3]) != ORD(']')))) {
|
||||||
/* no, check single match */
|
/* no, check single match */
|
||||||
if (sc == c)
|
if (sc == c)
|
||||||
/* note: sc is never NUL */
|
/* note: sc is never NUL */
|
||||||
|
@ -1079,13 +1079,13 @@ gmatch_cclass(const unsigned char *pat, unsigned char sc)
|
||||||
if (!(c = *p++))
|
if (!(c = *p++))
|
||||||
break;
|
break;
|
||||||
/* sub-bracket expressions */
|
/* sub-bracket expressions */
|
||||||
if (ord(c) == ord('[') && (
|
if (ord(c) == ORD('[') && (
|
||||||
/* collating element? */
|
/* collating element? */
|
||||||
ord(*p) == ord('.') ||
|
ord(*p) == ORD('.') ||
|
||||||
/* equivalence class? */
|
/* equivalence class? */
|
||||||
ord(*p) == ord('=') ||
|
ord(*p) == ORD('=') ||
|
||||||
/* character class? */
|
/* character class? */
|
||||||
ord(*p) == ord(':'))) {
|
ord(*p) == ORD(':'))) {
|
||||||
/* must stop with exactly the same c */
|
/* must stop with exactly the same c */
|
||||||
subc = *p++;
|
subc = *p++;
|
||||||
/* save away start of substring */
|
/* save away start of substring */
|
||||||
|
@ -1094,7 +1094,7 @@ gmatch_cclass(const unsigned char *pat, unsigned char sc)
|
||||||
while ((c = *p++))
|
while ((c = *p++))
|
||||||
/* but only this sequence... */
|
/* but only this sequence... */
|
||||||
if (c == subc && ISMAGIC(*p) &&
|
if (c == subc && ISMAGIC(*p) &&
|
||||||
ord(p[1]) == ord(']')) {
|
ord(p[1]) == ORD(']')) {
|
||||||
/* accept, terminate */
|
/* accept, terminate */
|
||||||
p += 2;
|
p += 2;
|
||||||
break;
|
break;
|
||||||
|
@ -1106,14 +1106,14 @@ gmatch_cclass(const unsigned char *pat, unsigned char sc)
|
||||||
strndupx(subp, s, p - s - 3, ATEMP);
|
strndupx(subp, s, p - s - 3, ATEMP);
|
||||||
debunk(subp, subp, p - s - 3 + 1);
|
debunk(subp, subp, p - s - 3 + 1);
|
||||||
/* whither subexpression */
|
/* whither subexpression */
|
||||||
if (ord(subc) == ord(':')) {
|
if (ord(subc) == ORD(':')) {
|
||||||
/* oops, not a range */
|
/* oops, not a range */
|
||||||
|
|
||||||
/* match single previous char */
|
/* match single previous char */
|
||||||
if (lc && (sc == lc))
|
if (lc && (sc == lc))
|
||||||
found = true;
|
found = true;
|
||||||
/* match hyphen-minus */
|
/* match hyphen-minus */
|
||||||
if (ord(sc) == ord('-'))
|
if (ord(sc) == ORD('-'))
|
||||||
found = true;
|
found = true;
|
||||||
/* handle cclass common part */
|
/* handle cclass common part */
|
||||||
goto cclass_common;
|
goto cclass_common;
|
||||||
|
@ -1151,7 +1151,7 @@ gmatch_cclass(const unsigned char *pat, unsigned char sc)
|
||||||
/* otherwise, just go on with the pattern string */
|
/* otherwise, just go on with the pattern string */
|
||||||
}
|
}
|
||||||
/* if we broke here, the bracket expression was invalid */
|
/* if we broke here, the bracket expression was invalid */
|
||||||
if (ord(sc) == ord('['))
|
if (ord(sc) == ORD('['))
|
||||||
/* initial opening bracket as literal match */
|
/* initial opening bracket as literal match */
|
||||||
return (pat);
|
return (pat);
|
||||||
/* or rather no match */
|
/* or rather no match */
|
||||||
|
@ -1661,6 +1661,15 @@ do_realpath(const char *upath)
|
||||||
if (mksh_abspath(upath)) {
|
if (mksh_abspath(upath)) {
|
||||||
/* upath is an absolute pathname */
|
/* upath is an absolute pathname */
|
||||||
strdupx(ipath, upath, ATEMP);
|
strdupx(ipath, upath, ATEMP);
|
||||||
|
#ifdef MKSH_DOSPATH
|
||||||
|
} else if (mksh_drvltr(upath)) {
|
||||||
|
/* upath is a drive-relative pathname */
|
||||||
|
if (getdrvwd(&ldest, ord(*upath)))
|
||||||
|
return (NULL);
|
||||||
|
/* A:foo -> A:/cwd/foo; A: -> A:/cwd */
|
||||||
|
ipath = shf_smprintf(Tf_sss, ldest,
|
||||||
|
upath[2] ? "/" : "", upath + 2);
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
/* upath is a relative pathname, prepend cwd */
|
/* upath is a relative pathname, prepend cwd */
|
||||||
if ((tp = ksh_get_wd()) == NULL || !mksh_abspath(tp))
|
if ((tp = ksh_get_wd()) == NULL || !mksh_abspath(tp))
|
||||||
|
@ -1695,6 +1704,7 @@ do_realpath(const char *upath)
|
||||||
continue;
|
continue;
|
||||||
else if (len == 2 && tp[1] == '.') {
|
else if (len == 2 && tp[1] == '.') {
|
||||||
/* strip off last pathname component */
|
/* strip off last pathname component */
|
||||||
|
/*XXX consider a rooted pathname */
|
||||||
while (xp > Xstring(xs, xp))
|
while (xp > Xstring(xs, xp))
|
||||||
if (mksh_cdirsep(*--xp))
|
if (mksh_cdirsep(*--xp))
|
||||||
break;
|
break;
|
||||||
|
@ -1762,11 +1772,23 @@ do_realpath(const char *upath)
|
||||||
* restart if symlink target is an absolute path,
|
* restart if symlink target is an absolute path,
|
||||||
* otherwise continue with currently resolved prefix
|
* otherwise continue with currently resolved prefix
|
||||||
*/
|
*/
|
||||||
|
#ifdef MKSH_DOSPATH
|
||||||
|
assemble_symlink:
|
||||||
|
#endif
|
||||||
/* append rest of current input path to link target */
|
/* append rest of current input path to link target */
|
||||||
tp = shf_smprintf(Tf_sss, ldest, *ip ? "/" : "", ip);
|
tp = shf_smprintf(Tf_sss, ldest, *ip ? "/" : "", ip);
|
||||||
afree(ipath, ATEMP);
|
afree(ipath, ATEMP);
|
||||||
ip = ipath = tp;
|
ip = ipath = tp;
|
||||||
if (!mksh_abspath(ldest)) {
|
if (!mksh_abspath(ipath)) {
|
||||||
|
#ifdef MKSH_DOSPATH
|
||||||
|
/* symlink target might be drive-relative */
|
||||||
|
if (mksh_drvltr(ipath)) {
|
||||||
|
if (getdrvwd(&ldest, ord(*ipath)))
|
||||||
|
goto notfound;
|
||||||
|
ip += 2;
|
||||||
|
goto assemble_symlink;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
/* symlink target is a relative path */
|
/* symlink target is a relative path */
|
||||||
xp = Xrestpos(xs, xp, pos);
|
xp = Xrestpos(xs, xp, pos);
|
||||||
} else
|
} else
|
||||||
|
@ -1775,7 +1797,7 @@ do_realpath(const char *upath)
|
||||||
/* symlink target is an absolute path */
|
/* symlink target is an absolute path */
|
||||||
xp = Xstring(xs, xp);
|
xp = Xstring(xs, xp);
|
||||||
beginning_of_a_pathname:
|
beginning_of_a_pathname:
|
||||||
/* assert: mksh_cdirsep((ip == ipath)[0]) */
|
/* assert: mksh_abspath(ip == ipath) */
|
||||||
/* assert: xp == xs.beg => start of path */
|
/* assert: xp == xs.beg => start of path */
|
||||||
|
|
||||||
/* exactly two leading slashes? (SUSv4 3.266) */
|
/* exactly two leading slashes? (SUSv4 3.266) */
|
||||||
|
@ -1783,6 +1805,14 @@ do_realpath(const char *upath)
|
||||||
/* keep them, e.g. for UNC pathnames */
|
/* keep them, e.g. for UNC pathnames */
|
||||||
Xput(xs, xp, '/');
|
Xput(xs, xp, '/');
|
||||||
}
|
}
|
||||||
|
#ifdef MKSH_DOSPATH
|
||||||
|
/* drive letter? */
|
||||||
|
if (mksh_drvltr(ip)) {
|
||||||
|
/* keep it */
|
||||||
|
Xput(xs, xp, *ip++);
|
||||||
|
Xput(xs, xp, *ip++);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* otherwise (no symlink) merely go on */
|
/* otherwise (no symlink) merely go on */
|
||||||
|
@ -1932,6 +1962,15 @@ make_path(const char *cwd, const char *file,
|
||||||
* .. ..
|
* .. ..
|
||||||
* ./foo foo
|
* ./foo foo
|
||||||
* foo/../../../bar ../../bar
|
* foo/../../../bar ../../bar
|
||||||
|
* C:/foo/../.. C:/
|
||||||
|
* C:. C:
|
||||||
|
* C:.. C:..
|
||||||
|
* C:foo/../../blah C:../blah
|
||||||
|
*
|
||||||
|
* XXX consider a rooted pathname: we cannot really 'cd ..' for
|
||||||
|
* pathnames like: '/', 'c:/', '//foo', '//foo/', '/@unixroot/'
|
||||||
|
* (no effect), 'c:', 'c:.' (effect is retaining the '../') but
|
||||||
|
* we need to honour this throughout the shell
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
simplify_path(char *p)
|
simplify_path(char *p)
|
||||||
|
@ -1939,6 +1978,17 @@ simplify_path(char *p)
|
||||||
char *dp, *ip, *sp, *tp;
|
char *dp, *ip, *sp, *tp;
|
||||||
size_t len;
|
size_t len;
|
||||||
bool needslash;
|
bool needslash;
|
||||||
|
#ifdef MKSH_DOSPATH
|
||||||
|
bool needdot = true;
|
||||||
|
|
||||||
|
/* keep drive letter */
|
||||||
|
if (mksh_drvltr(p)) {
|
||||||
|
p += 2;
|
||||||
|
needdot = false;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#define needdot true
|
||||||
|
#endif
|
||||||
|
|
||||||
switch (*p) {
|
switch (*p) {
|
||||||
case 0:
|
case 0:
|
||||||
|
@ -1977,7 +2027,7 @@ simplify_path(char *p)
|
||||||
/* just continue with the next one */
|
/* just continue with the next one */
|
||||||
continue;
|
continue;
|
||||||
else if (len == 2 && tp[1] == '.') {
|
else if (len == 2 && tp[1] == '.') {
|
||||||
/* parent level, but how? */
|
/* parent level, but how? (see above) */
|
||||||
if (mksh_abspath(p))
|
if (mksh_abspath(p))
|
||||||
/* absolute path, only one way */
|
/* absolute path, only one way */
|
||||||
goto strip_last_component;
|
goto strip_last_component;
|
||||||
|
@ -2016,10 +2066,15 @@ simplify_path(char *p)
|
||||||
needslash = true;
|
needslash = true;
|
||||||
/* try next component */
|
/* try next component */
|
||||||
}
|
}
|
||||||
if (dp == p)
|
if (dp == p) {
|
||||||
/* empty path -> dot */
|
/* empty path -> dot (or slash, when absolute) */
|
||||||
*dp++ = needslash ? '/' : '.';
|
if (needslash)
|
||||||
|
*dp++ = '/';
|
||||||
|
else if (needdot)
|
||||||
|
*dp++ = '.';
|
||||||
|
}
|
||||||
*dp = '\0';
|
*dp = '\0';
|
||||||
|
#undef needdot
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -2133,6 +2188,18 @@ c_cd(const char **wp)
|
||||||
return (2);
|
return (2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MKSH_DOSPATH
|
||||||
|
tryp = NULL;
|
||||||
|
if (mksh_drvltr(dir) && !mksh_cdirsep(dir[2]) &&
|
||||||
|
!getdrvwd(&tryp, ord(*dir))) {
|
||||||
|
dir = shf_smprintf(Tf_sss, tryp,
|
||||||
|
dir[2] ? "/" : "", dir + 2);
|
||||||
|
afree(tryp, ATEMP);
|
||||||
|
afree(allocd, ATEMP);
|
||||||
|
allocd = dir;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef MKSH__NO_PATH_MAX
|
#ifdef MKSH__NO_PATH_MAX
|
||||||
/* only a first guess; make_path will enlarge xs if necessary */
|
/* only a first guess; make_path will enlarge xs if necessary */
|
||||||
XinitN(xs, 1024, ATEMP);
|
XinitN(xs, 1024, ATEMP);
|
||||||
|
|
148
src/os2.c
148
src/os2.c
|
@ -1,5 +1,5 @@
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 2015
|
* Copyright (c) 2015, 2017
|
||||||
* KO Myung-Hun <komh@chollian.net>
|
* KO Myung-Hun <komh@chollian.net>
|
||||||
* Copyright (c) 2017
|
* Copyright (c) 2017
|
||||||
* mirabilos <m@mirbsd.org>
|
* mirabilos <m@mirbsd.org>
|
||||||
|
@ -26,18 +26,18 @@
|
||||||
#include "sh.h"
|
#include "sh.h"
|
||||||
|
|
||||||
#include <klibc/startup.h>
|
#include <klibc/startup.h>
|
||||||
|
#include <errno.h>
|
||||||
#include <io.h>
|
#include <io.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <process.h>
|
#include <process.h>
|
||||||
|
|
||||||
__RCSID("$MirOS: src/bin/mksh/os2.c,v 1.2 2017/04/29 22:04:29 tg Exp $");
|
__RCSID("$MirOS: src/bin/mksh/os2.c,v 1.8 2017/12/22 16:41:42 tg Exp $");
|
||||||
|
|
||||||
static char *remove_trailing_dots(char *);
|
static char *remove_trailing_dots(char *);
|
||||||
static int access_stat_ex(int (*)(), const char *, void *);
|
static int access_stat_ex(int (*)(), const char *, void *);
|
||||||
static int test_exec_exist(const char *, char *);
|
static int test_exec_exist(const char *, char *);
|
||||||
static void response(int *, const char ***);
|
static void response(int *, const char ***);
|
||||||
static char *make_response_file(char * const *);
|
static char *make_response_file(char * const *);
|
||||||
static void env_slashify(void);
|
|
||||||
static void add_temp(const char *);
|
static void add_temp(const char *);
|
||||||
static void cleanup_temps(void);
|
static void cleanup_temps(void);
|
||||||
static void cleanup(void);
|
static void cleanup(void);
|
||||||
|
@ -169,44 +169,12 @@ init_extlibpath(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Convert backslashes of environmental variables to forward slahes.
|
|
||||||
* A backslash may be used as an escaped character when doing 'echo'.
|
|
||||||
* This leads to an unexpected behavior.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
env_slashify(void)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* PATH and TMPDIR are used by OS/2 as well. That is, they may
|
|
||||||
* have backslashes as a directory separator.
|
|
||||||
* BEGINLIBPATH and ENDLIBPATH are special variables on OS/2.
|
|
||||||
*/
|
|
||||||
const char *var_list[] = {
|
|
||||||
"PATH",
|
|
||||||
"TMPDIR",
|
|
||||||
"BEGINLIBPATH",
|
|
||||||
"ENDLIBPATH",
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
const char **var;
|
|
||||||
char *value;
|
|
||||||
|
|
||||||
for (var = var_list; *var; var++) {
|
|
||||||
value = getenv(*var);
|
|
||||||
|
|
||||||
if (value)
|
|
||||||
_fnslashify(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
os2_init(int *argcp, const char ***argvp)
|
os2_init(int *argcp, const char ***argvp)
|
||||||
{
|
{
|
||||||
response(argcp, argvp);
|
response(argcp, argvp);
|
||||||
|
|
||||||
init_extlibpath();
|
init_extlibpath();
|
||||||
env_slashify();
|
|
||||||
|
|
||||||
if (!isatty(STDIN_FILENO))
|
if (!isatty(STDIN_FILENO))
|
||||||
setmode(STDIN_FILENO, O_BINARY);
|
setmode(STDIN_FILENO, O_BINARY);
|
||||||
|
@ -361,30 +329,13 @@ real_exec_name(const char *name)
|
||||||
return (real_name);
|
return (real_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* OS/2 can process a command line up to 32 KiB */
|
|
||||||
#define MAX_CMD_LINE_LEN 32768
|
|
||||||
|
|
||||||
/* make a response file to pass a very long command line */
|
/* make a response file to pass a very long command line */
|
||||||
static char *
|
static char *
|
||||||
make_response_file(char * const *argv)
|
make_response_file(char * const *argv)
|
||||||
{
|
{
|
||||||
char rsp_name_arg[] = "@mksh-rsp-XXXXXX";
|
char rsp_name_arg[] = "@mksh-rsp-XXXXXX";
|
||||||
char *rsp_name = &rsp_name_arg[1];
|
char *rsp_name = &rsp_name_arg[1];
|
||||||
int arg_len = 0;
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; argv[i]; i++)
|
|
||||||
arg_len += strlen(argv[i]) + 1;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If a length of command line is longer than MAX_CMD_LINE_LEN, then
|
|
||||||
* use a response file. OS/2 cannot process a command line longer
|
|
||||||
* than 32K. Of course, a response file cannot be recognised by a
|
|
||||||
* normal OS/2 program, that is, neither non-EMX or non-kLIBC. But
|
|
||||||
* it cannot accept a command line longer than 32K in itself. So
|
|
||||||
* using a response file in this case, is an acceptable solution.
|
|
||||||
*/
|
|
||||||
if (arg_len > MAX_CMD_LINE_LEN) {
|
|
||||||
int fd;
|
int fd;
|
||||||
char *result;
|
char *result;
|
||||||
|
|
||||||
|
@ -400,10 +351,8 @@ make_response_file(char * const *argv)
|
||||||
close(fd);
|
close(fd);
|
||||||
add_temp(rsp_name);
|
add_temp(rsp_name);
|
||||||
strdupx(result, rsp_name_arg, ATEMP);
|
strdupx(result, rsp_name_arg, ATEMP);
|
||||||
return (result);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (NULL);
|
return (result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* alias of execve() */
|
/* alias of execve() */
|
||||||
|
@ -416,12 +365,12 @@ execve(const char *name, char * const *argv, char * const *envp)
|
||||||
const char *exec_name;
|
const char *exec_name;
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
char sign[2];
|
char sign[2];
|
||||||
char *rsp_argv[3];
|
|
||||||
char *rsp_name_arg;
|
|
||||||
int pid;
|
int pid;
|
||||||
int status;
|
int status;
|
||||||
int fd;
|
int fd;
|
||||||
int rc;
|
int rc;
|
||||||
|
int saved_mode;
|
||||||
|
int saved_errno;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* #! /bin/sh : append .exe
|
* #! /bin/sh : append .exe
|
||||||
|
@ -461,23 +410,41 @@ execve(const char *name, char * const *argv, char * const *envp)
|
||||||
if (errno == ENOEXEC)
|
if (errno == ENOEXEC)
|
||||||
return (-1);
|
return (-1);
|
||||||
|
|
||||||
rsp_name_arg = make_response_file(argv);
|
/*
|
||||||
|
* Normal OS/2 programs expect that standard IOs, especially stdin,
|
||||||
if (rsp_name_arg) {
|
* are opened in text mode at the startup. By the way, on OS/2 kLIBC
|
||||||
rsp_argv[0] = argv[0];
|
* child processes inherit a translation mode of a parent process.
|
||||||
rsp_argv[1] = rsp_name_arg;
|
* As a result, if stdin is set to binary mode in a parent process,
|
||||||
rsp_argv[2] = NULL;
|
* stdin of child processes is opened in binary mode as well at the
|
||||||
|
* startup. In this case, some programs such as sed suffer from CR.
|
||||||
argv = rsp_argv;
|
*/
|
||||||
}
|
saved_mode = setmode(STDIN_FILENO, O_TEXT);
|
||||||
|
|
||||||
pid = spawnve(P_NOWAIT, exec_name, argv, envp);
|
pid = spawnve(P_NOWAIT, exec_name, argv, envp);
|
||||||
|
saved_errno = errno;
|
||||||
|
|
||||||
|
/* arguments too long? */
|
||||||
|
if (pid == -1 && saved_errno == EINVAL) {
|
||||||
|
/* retry with a response file */
|
||||||
|
char *rsp_name_arg = make_response_file(argv);
|
||||||
|
|
||||||
|
if (rsp_name_arg) {
|
||||||
|
char *rsp_argv[3] = { argv[0], rsp_name_arg, NULL };
|
||||||
|
|
||||||
|
pid = spawnve(P_NOWAIT, exec_name, rsp_argv, envp);
|
||||||
|
saved_errno = errno;
|
||||||
|
|
||||||
afree(rsp_name_arg, ATEMP);
|
afree(rsp_name_arg, ATEMP);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* restore translation mode of stdin */
|
||||||
|
setmode(STDIN_FILENO, saved_mode);
|
||||||
|
|
||||||
if (pid == -1) {
|
if (pid == -1) {
|
||||||
cleanup_temps();
|
cleanup_temps();
|
||||||
|
|
||||||
|
errno = saved_errno;
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -557,3 +524,52 @@ cleanup(void)
|
||||||
{
|
{
|
||||||
cleanup_temps();
|
cleanup_temps();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
getdrvwd(char **cpp, unsigned int drvltr)
|
||||||
|
{
|
||||||
|
PBYTE cp;
|
||||||
|
ULONG sz;
|
||||||
|
APIRET rc;
|
||||||
|
ULONG drvno;
|
||||||
|
|
||||||
|
if (DosQuerySysInfo(QSV_MAX_PATH_LENGTH, QSV_MAX_PATH_LENGTH,
|
||||||
|
&sz, sizeof(sz)) != 0) {
|
||||||
|
errno = EDOOFUS;
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* allocate 'X:/' plus sz plus NUL */
|
||||||
|
checkoktoadd((size_t)sz, (size_t)4);
|
||||||
|
cp = aresize(*cpp, (size_t)sz + (size_t)4, ATEMP);
|
||||||
|
cp[0] = ksh_toupper(drvltr);
|
||||||
|
cp[1] = ':';
|
||||||
|
cp[2] = '/';
|
||||||
|
drvno = ksh_numuc(cp[0]) + 1;
|
||||||
|
/* NUL is part of space within buffer passed */
|
||||||
|
++sz;
|
||||||
|
if ((rc = DosQueryCurrentDir(drvno, cp + 3, &sz)) == 0) {
|
||||||
|
/* success! */
|
||||||
|
*cpp = cp;
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
afree(cp, ATEMP);
|
||||||
|
*cpp = NULL;
|
||||||
|
switch (rc) {
|
||||||
|
case 15: /* invalid drive */
|
||||||
|
errno = ENOTBLK;
|
||||||
|
break;
|
||||||
|
case 26: /* not dos disk */
|
||||||
|
errno = ENODEV;
|
||||||
|
break;
|
||||||
|
case 108: /* drive locked */
|
||||||
|
errno = EDEADLK;
|
||||||
|
break;
|
||||||
|
case 111: /* buffer overflow */
|
||||||
|
errno = ENAMETOOLONG;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
errno = EINVAL;
|
||||||
|
}
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
69
src/sh.h
69
src/sh.h
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright © 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
|
* Copyright © 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
|
||||||
* 2011, 2012, 2013, 2014, 2015, 2016, 2017
|
* 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018
|
||||||
* mirabilos <m@mirbsd.org>
|
* mirabilos <m@mirbsd.org>
|
||||||
*
|
*
|
||||||
* Provided that these terms and disclaimer and all copyright notices
|
* Provided that these terms and disclaimer and all copyright notices
|
||||||
|
@ -182,9 +182,9 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef EXTERN
|
#ifdef EXTERN
|
||||||
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.841 2017/08/29 13:38:31 tg Exp $");
|
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.858 2018/01/14 01:47:36 tg Exp $");
|
||||||
#endif
|
#endif
|
||||||
#define MKSH_VERSION "R56 2017/08/29"
|
#define MKSH_VERSION "R56 2018/01/14"
|
||||||
|
|
||||||
/* arithmetic types: C implementation */
|
/* arithmetic types: C implementation */
|
||||||
#if !HAVE_CAN_INTTYPES
|
#if !HAVE_CAN_INTTYPES
|
||||||
|
@ -556,7 +556,7 @@ extern int __cdecl setegid(gid_t);
|
||||||
* low-bit7 at least on cp1047 so YMMV
|
* low-bit7 at least on cp1047 so YMMV
|
||||||
*/
|
*/
|
||||||
#define MAGIC KSH_BEL /* prefix for *?[!{,} during expand */
|
#define MAGIC KSH_BEL /* prefix for *?[!{,} during expand */
|
||||||
#define ISMAGIC(c) (ord(c) == ord(MAGIC))
|
#define ISMAGIC(c) (ord(c) == ORD(MAGIC))
|
||||||
|
|
||||||
EXTERN const char *safe_prompt; /* safe prompt if PS1 substitution fails */
|
EXTERN const char *safe_prompt; /* safe prompt if PS1 substitution fails */
|
||||||
|
|
||||||
|
@ -643,7 +643,7 @@ char *ucstrstr(char *, const char *);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (!defined(MKSH_BUILDMAKEFILE4BSD) && !defined(MKSH_BUILDSH)) || (MKSH_BUILD_R != 562)
|
#if (!defined(MKSH_BUILDMAKEFILE4BSD) && !defined(MKSH_BUILDSH)) || (MKSH_BUILD_R != 563)
|
||||||
#error Must run Build.sh to compile this.
|
#error Must run Build.sh to compile this.
|
||||||
extern void thiswillneverbedefinedIhope(void);
|
extern void thiswillneverbedefinedIhope(void);
|
||||||
int
|
int
|
||||||
|
@ -804,7 +804,7 @@ struct sretrace_info;
|
||||||
struct yyrecursive_state;
|
struct yyrecursive_state;
|
||||||
|
|
||||||
EXTERN struct sretrace_info *retrace_info;
|
EXTERN struct sretrace_info *retrace_info;
|
||||||
EXTERN int subshell_nesting_type;
|
EXTERN unsigned int subshell_nesting_type;
|
||||||
|
|
||||||
extern struct env {
|
extern struct env {
|
||||||
ALLOC_ITEM alloc_INT; /* internal, do not touch */
|
ALLOC_ITEM alloc_INT; /* internal, do not touch */
|
||||||
|
@ -1469,7 +1469,26 @@ EXTERN char ifs0;
|
||||||
#define C_UNDER CiUNDER /* _ underscore */
|
#define C_UNDER CiUNDER /* _ underscore */
|
||||||
|
|
||||||
/* identity transform of octet */
|
/* identity transform of octet */
|
||||||
|
#if defined(DEBUG) && defined(__GNUC__) && !defined(__ICC) && \
|
||||||
|
!defined(__INTEL_COMPILER) && !defined(__SUNPRO_C)
|
||||||
|
extern unsigned int eek_ord;
|
||||||
|
#define ORD(c) ((size_t)(c) > 0xFF ? eek_ord : \
|
||||||
|
((unsigned int)(unsigned char)(c)))
|
||||||
|
#define ord(c) __builtin_choose_expr( \
|
||||||
|
__builtin_types_compatible_p(__typeof__(c), char) || \
|
||||||
|
__builtin_types_compatible_p(__typeof__(c), unsigned char), \
|
||||||
|
((unsigned int)(unsigned char)(c)), ({ \
|
||||||
|
size_t ord_c = (c); \
|
||||||
|
\
|
||||||
|
if (ord_c > (size_t)0xFFU) \
|
||||||
|
internal_errorf("%s:%d:ord(%zX)", \
|
||||||
|
__FILE__, __LINE__, ord_c); \
|
||||||
|
((unsigned int)(unsigned char)(ord_c)); \
|
||||||
|
}))
|
||||||
|
#else
|
||||||
#define ord(c) ((unsigned int)(unsigned char)(c))
|
#define ord(c) ((unsigned int)(unsigned char)(c))
|
||||||
|
#define ORD(c) ord(c) /* may evaluate arguments twice */
|
||||||
|
#endif
|
||||||
#if defined(MKSH_EBCDIC) || defined(MKSH_FAUX_EBCDIC)
|
#if defined(MKSH_EBCDIC) || defined(MKSH_FAUX_EBCDIC)
|
||||||
EXTERN unsigned short ebcdic_map[256];
|
EXTERN unsigned short ebcdic_map[256];
|
||||||
EXTERN unsigned char ebcdic_rtt_toascii[256];
|
EXTERN unsigned char ebcdic_rtt_toascii[256];
|
||||||
|
@ -1492,20 +1511,22 @@ extern void ebcdic_init(void);
|
||||||
#ifdef MKSH_EBCDIC
|
#ifdef MKSH_EBCDIC
|
||||||
#define ksh_isctrl(c) (ord(c) < 0x40 || ord(c) == 0xFF)
|
#define ksh_isctrl(c) (ord(c) < 0x40 || ord(c) == 0xFF)
|
||||||
#else
|
#else
|
||||||
#define ksh_isctrl(c) ((ord(c) & 0x7F) < 0x20 || (c) == 0x7F)
|
#define ksh_isctrl(c) ((ord(c) & 0x7F) < 0x20 || ord(c) == 0x7F)
|
||||||
#endif
|
#endif
|
||||||
/* new fast character classes */
|
/* new fast character classes */
|
||||||
#define ctype(c,t) tobool(ksh_ctypes[ord(c)] & (t))
|
#define ctype(c,t) tobool(ksh_ctypes[ord(c)] & (t))
|
||||||
|
#define cinttype(c,t) ((c) >= 0 && (c) <= 0xFF ? \
|
||||||
|
tobool(ksh_ctypes[(unsigned char)(c)] & (t)) : false)
|
||||||
/* helper functions */
|
/* helper functions */
|
||||||
#define ksh_isdash(s) tobool(ord((s)[0]) == '-' && ord((s)[1]) == '\0')
|
#define ksh_isdash(s) tobool(ord((s)[0]) == '-' && ord((s)[1]) == '\0')
|
||||||
/* invariant distance even in EBCDIC */
|
/* invariant distance even in EBCDIC */
|
||||||
#define ksh_tolower(c) (ctype(c, C_UPPER) ? (c) - 'A' + 'a' : (c))
|
#define ksh_tolower(c) (ctype(c, C_UPPER) ? (c) - 'A' + 'a' : (c))
|
||||||
#define ksh_toupper(c) (ctype(c, C_LOWER) ? (c) - 'a' + 'A' : (c))
|
#define ksh_toupper(c) (ctype(c, C_LOWER) ? (c) - 'a' + 'A' : (c))
|
||||||
/* strictly speaking rtt2asc() here, but this works even in EBCDIC */
|
/* strictly speaking rtt2asc() here, but this works even in EBCDIC */
|
||||||
#define ksh_numdig(c) (ord(c) - ord('0'))
|
#define ksh_numdig(c) (ord(c) - ORD('0'))
|
||||||
#define ksh_numuc(c) (rtt2asc(c) - rtt2asc('A'))
|
#define ksh_numuc(c) (rtt2asc(c) - rtt2asc('A'))
|
||||||
#define ksh_numlc(c) (rtt2asc(c) - rtt2asc('a'))
|
#define ksh_numlc(c) (rtt2asc(c) - rtt2asc('a'))
|
||||||
#define ksh_toctrl(c) asc2rtt(ord(c) == ord('?') ? 0x7F : rtt2asc(c) & 0x9F)
|
#define ksh_toctrl(c) asc2rtt(ord(c) == ORD('?') ? 0x7F : rtt2asc(c) & 0x9F)
|
||||||
#define ksh_unctrl(c) asc2rtt(rtt2asc(c) ^ 0x40U)
|
#define ksh_unctrl(c) asc2rtt(rtt2asc(c) ^ 0x40U)
|
||||||
|
|
||||||
/* Argument parsing for built-in commands and getopts command */
|
/* Argument parsing for built-in commands and getopts command */
|
||||||
|
@ -1599,7 +1620,7 @@ EXTERN mksh_ari_t x_lins E_INIT(24);
|
||||||
#define shf_fileno(shf) ((shf)->fd)
|
#define shf_fileno(shf) ((shf)->fd)
|
||||||
#define shf_setfileno(shf,nfd) ((shf)->fd = (nfd))
|
#define shf_setfileno(shf,nfd) ((shf)->fd = (nfd))
|
||||||
#define shf_getc_i(shf) ((shf)->rnleft > 0 ? \
|
#define shf_getc_i(shf) ((shf)->rnleft > 0 ? \
|
||||||
(shf)->rnleft--, *(shf)->rp++ : \
|
(shf)->rnleft--, (int)ord(*(shf)->rp++) : \
|
||||||
shf_getchar(shf))
|
shf_getchar(shf))
|
||||||
#define shf_putc_i(c, shf) ((shf)->wnleft == 0 ? \
|
#define shf_putc_i(c, shf) ((shf)->wnleft == 0 ? \
|
||||||
shf_putchar((uint8_t)(c), (shf)) : \
|
shf_putchar((uint8_t)(c), (shf)) : \
|
||||||
|
@ -2500,6 +2521,7 @@ void shprintf(const char *, ...)
|
||||||
MKSH_A_FORMAT(__printf__, 1, 2);
|
MKSH_A_FORMAT(__printf__, 1, 2);
|
||||||
int can_seek(int);
|
int can_seek(int);
|
||||||
void initio(void);
|
void initio(void);
|
||||||
|
void recheck_ctype(void);
|
||||||
int ksh_dup2(int, int, bool);
|
int ksh_dup2(int, int, bool);
|
||||||
short savefd(int);
|
short savefd(int);
|
||||||
void restfd(int, int);
|
void restfd(int, int);
|
||||||
|
@ -2734,27 +2756,32 @@ extern int tty_init_fd(void); /* initialise tty_fd, tty_devtty */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef MKSH_DOSPATH
|
#ifdef MKSH_DOSPATH
|
||||||
|
#define mksh_drvltr(s) __extension__({ \
|
||||||
|
const char *mksh_drvltr_s = (s); \
|
||||||
|
(ctype(mksh_drvltr_s[0], C_ALPHA) && mksh_drvltr_s[1] == ':'); \
|
||||||
|
})
|
||||||
#define mksh_abspath(s) __extension__({ \
|
#define mksh_abspath(s) __extension__({ \
|
||||||
const char *mksh_abspath_s = (s); \
|
const char *mksh_abspath_s = (s); \
|
||||||
(mksh_cdirsep(mksh_abspath_s[0]) || \
|
(mksh_cdirsep(mksh_abspath_s[0]) || \
|
||||||
(ctype(mksh_abspath_s[0], C_ALPHA) && \
|
(mksh_drvltr(mksh_abspath_s) && \
|
||||||
mksh_abspath_s[1] == ':')); \
|
mksh_cdirsep(mksh_abspath_s[2]))); \
|
||||||
})
|
})
|
||||||
#define mksh_cdirsep(c) __extension__({ \
|
#define mksh_cdirsep(c) __extension__({ \
|
||||||
char mksh_cdirsep_c = (c); \
|
char mksh_cdirsep_c = (c); \
|
||||||
(mksh_cdirsep_c == '/' || mksh_cdirsep_c == '\\'); \
|
(mksh_cdirsep_c == '/' || mksh_cdirsep_c == '\\'); \
|
||||||
})
|
})
|
||||||
#define mksh_sdirsep(s) __extension__({ \
|
#define mksh_sdirsep(s) strpbrk((s), "/\\")
|
||||||
const char *mksh_sdirsep_s = (s); \
|
#define mksh_vdirsep(s) __extension__({ \
|
||||||
((char *)((ctype(mksh_sdirsep_s[0], C_ALPHA) && \
|
const char *mksh_vdirsep_s = (s); \
|
||||||
mksh_sdirsep_s[1] == ':' && \
|
(((mksh_drvltr(mksh_vdirsep_s) && \
|
||||||
!mksh_cdirsep(mksh_sdirsep_s[2])) ? \
|
!mksh_cdirsep(mksh_vdirsep_s[2])) ? (!0) : \
|
||||||
(mksh_sdirsep_s + 1) : strpbrk(mksh_sdirsep_s, "/\\"))); \
|
(mksh_sdirsep(mksh_vdirsep_s) != NULL)) && \
|
||||||
|
(strcmp(mksh_vdirsep_s, T_builtin) != 0)); \
|
||||||
})
|
})
|
||||||
#define mksh_vdirsep(s) (mksh_sdirsep((s)) != NULL)
|
int getdrvwd(char **, unsigned int);
|
||||||
#else
|
#else
|
||||||
#define mksh_abspath(s) (ord((s)[0]) == ord('/'))
|
#define mksh_abspath(s) (ord((s)[0]) == ORD('/'))
|
||||||
#define mksh_cdirsep(c) (ord(c) == ord('/'))
|
#define mksh_cdirsep(c) (ord(c) == ORD('/'))
|
||||||
#define mksh_sdirsep(s) strchr((s), '/')
|
#define mksh_sdirsep(s) strchr((s), '/')
|
||||||
#define mksh_vdirsep(s) vstrchr((s), '/')
|
#define mksh_vdirsep(s) vstrchr((s), '/')
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2011,
|
* Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2011,
|
||||||
* 2012, 2013, 2015, 2016, 2017
|
* 2012, 2013, 2015, 2016, 2017, 2018
|
||||||
* mirabilos <m@mirbsd.org>
|
* mirabilos <m@mirbsd.org>
|
||||||
* Copyright (c) 2015
|
* Copyright (c) 2015
|
||||||
* Daniel Richard G. <skunk@iSKUNK.ORG>
|
* Daniel Richard G. <skunk@iSKUNK.ORG>
|
||||||
|
@ -27,7 +27,7 @@
|
||||||
|
|
||||||
#include "sh.h"
|
#include "sh.h"
|
||||||
|
|
||||||
__RCSID("$MirOS: src/bin/mksh/shf.c,v 1.95 2017/05/05 22:45:58 tg Exp $");
|
__RCSID("$MirOS: src/bin/mksh/shf.c,v 1.97 2018/01/14 01:28:16 tg Exp $");
|
||||||
|
|
||||||
/* flags to shf_emptybuf() */
|
/* flags to shf_emptybuf() */
|
||||||
#define EB_READSW 0x01 /* about to switch to reading */
|
#define EB_READSW 0x01 /* about to switch to reading */
|
||||||
|
@ -554,7 +554,7 @@ shf_getchar(struct shf *shf)
|
||||||
if (shf->rnleft == 0 && (shf_fillbuf(shf) == -1 || shf->rnleft == 0))
|
if (shf->rnleft == 0 && (shf_fillbuf(shf) == -1 || shf->rnleft == 0))
|
||||||
return (-1);
|
return (-1);
|
||||||
--shf->rnleft;
|
--shf->rnleft;
|
||||||
return (*shf->rp++);
|
return (ord(*shf->rp++));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1253,7 +1253,7 @@ set_ifs(const char *s)
|
||||||
* Not only do they require all 8 bits instead of 7, if chars are
|
* Not only do they require all 8 bits instead of 7, if chars are
|
||||||
* signed, they will have negative integer values! Something like
|
* signed, they will have negative integer values! Something like
|
||||||
* (c - 'A') could actually become (c + 63)! Use the ord() macro to
|
* (c - 'A') could actually become (c + 63)! Use the ord() macro to
|
||||||
* ensure you're getting a value in [0, 255].
|
* ensure you're getting a value in [0, 255] (ORD for constants).
|
||||||
* 4. '\n' is actually NL (0x15, U+0085) instead of LF (0x25, U+000A).
|
* 4. '\n' is actually NL (0x15, U+0085) instead of LF (0x25, U+000A).
|
||||||
* EBCDIC has a proper newline character instead of "emulating" one
|
* EBCDIC has a proper newline character instead of "emulating" one
|
||||||
* with line feeds, although this is mapped to LF for our purposes.
|
* with line feeds, although this is mapped to LF for our purposes.
|
||||||
|
|
83
src/syn.c
83
src/syn.c
|
@ -2,7 +2,8 @@
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009,
|
* Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009,
|
||||||
* 2011, 2012, 2013, 2014, 2015, 2016, 2017
|
* 2011, 2012, 2013, 2014, 2015, 2016, 2017,
|
||||||
|
* 2018
|
||||||
* mirabilos <m@mirbsd.org>
|
* mirabilos <m@mirbsd.org>
|
||||||
*
|
*
|
||||||
* Provided that these terms and disclaimer and all copyright notices
|
* Provided that these terms and disclaimer and all copyright notices
|
||||||
|
@ -23,7 +24,7 @@
|
||||||
|
|
||||||
#include "sh.h"
|
#include "sh.h"
|
||||||
|
|
||||||
__RCSID("$MirOS: src/bin/mksh/syn.c,v 1.124 2017/05/05 22:53:31 tg Exp $");
|
__RCSID("$MirOS: src/bin/mksh/syn.c,v 1.127 2018/01/14 00:22:30 tg Exp $");
|
||||||
|
|
||||||
struct nesting_state {
|
struct nesting_state {
|
||||||
int start_token; /* token than began nesting (eg, FOR) */
|
int start_token; /* token than began nesting (eg, FOR) */
|
||||||
|
@ -35,7 +36,7 @@ struct yyrecursive_state {
|
||||||
struct yyrecursive_state *next;
|
struct yyrecursive_state *next;
|
||||||
struct ioword **old_herep;
|
struct ioword **old_herep;
|
||||||
int old_symbol;
|
int old_symbol;
|
||||||
int old_nesting_type;
|
unsigned int old_nesting_type;
|
||||||
bool old_reject;
|
bool old_reject;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -75,7 +76,10 @@ static int symbol; /* yylex value */
|
||||||
#define ACCEPT (reject = false)
|
#define ACCEPT (reject = false)
|
||||||
#define token(cf) ((reject) ? (ACCEPT, symbol) : (symbol = yylex(cf)))
|
#define token(cf) ((reject) ? (ACCEPT, symbol) : (symbol = yylex(cf)))
|
||||||
#define tpeek(cf) ((reject) ? (symbol) : (REJECT, symbol = yylex(cf)))
|
#define tpeek(cf) ((reject) ? (symbol) : (REJECT, symbol = yylex(cf)))
|
||||||
#define musthave(c,cf) do { if (token(cf) != (c)) syntaxerr(NULL); } while (/* CONSTCOND */ 0)
|
#define musthave(c,cf) do { \
|
||||||
|
if ((unsigned int)token(cf) != (unsigned int)(c)) \
|
||||||
|
syntaxerr(NULL); \
|
||||||
|
} while (/* CONSTCOND */ 0)
|
||||||
|
|
||||||
static const char Tcbrace[] = "}";
|
static const char Tcbrace[] = "}";
|
||||||
static const char Tesac[] = "esac";
|
static const char Tesac[] = "esac";
|
||||||
|
@ -91,7 +95,7 @@ yyparse(bool doalias)
|
||||||
c = tpeek(0);
|
c = tpeek(0);
|
||||||
if (c == 0 && !outtree)
|
if (c == 0 && !outtree)
|
||||||
outtree = newtp(TEOF);
|
outtree = newtp(TEOF);
|
||||||
else if (!ctype(c, C_LF | C_NUL))
|
else if (!cinttype(c, C_LF | C_NUL))
|
||||||
syntaxerr(NULL);
|
syntaxerr(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -330,7 +334,7 @@ get_command(int cf, int sALIAS)
|
||||||
XPput(args, yylval.cp);
|
XPput(args, yylval.cp);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ord('(' /*)*/):
|
case ORD('(' /*)*/):
|
||||||
if (XPsize(args) == 0 && XPsize(vars) == 1 &&
|
if (XPsize(args) == 0 && XPsize(vars) == 1 &&
|
||||||
is_wdvarassign(yylval.cp)) {
|
is_wdvarassign(yylval.cp)) {
|
||||||
char *tcp;
|
char *tcp;
|
||||||
|
@ -386,18 +390,18 @@ get_command(int cf, int sALIAS)
|
||||||
Leave:
|
Leave:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ord('(' /*)*/): {
|
case ORD('(' /*)*/): {
|
||||||
int subshell_nesting_type_saved;
|
unsigned int subshell_nesting_type_saved;
|
||||||
Subshell:
|
Subshell:
|
||||||
subshell_nesting_type_saved = subshell_nesting_type;
|
subshell_nesting_type_saved = subshell_nesting_type;
|
||||||
subshell_nesting_type = ord(')');
|
subshell_nesting_type = ORD(')');
|
||||||
t = nested(TPAREN, ord('('), ord(')'), sALIAS);
|
t = nested(TPAREN, ORD('('), ORD(')'), sALIAS);
|
||||||
subshell_nesting_type = subshell_nesting_type_saved;
|
subshell_nesting_type = subshell_nesting_type_saved;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case ord('{' /*}*/):
|
case ORD('{' /*}*/):
|
||||||
t = nested(TBRACE, ord('{'), ord('}'), sALIAS);
|
t = nested(TBRACE, ORD('{'), ORD('}'), sALIAS);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MDPAREN:
|
case MDPAREN:
|
||||||
|
@ -407,8 +411,8 @@ get_command(int cf, int sALIAS)
|
||||||
switch (token(LETEXPR)) {
|
switch (token(LETEXPR)) {
|
||||||
case LWORD:
|
case LWORD:
|
||||||
break;
|
break;
|
||||||
case ord('(' /*)*/):
|
case ORD('(' /*)*/):
|
||||||
c = ord('(');
|
c = ORD('(');
|
||||||
goto Subshell;
|
goto Subshell;
|
||||||
default:
|
default:
|
||||||
syntaxerr(NULL);
|
syntaxerr(NULL);
|
||||||
|
@ -554,8 +558,8 @@ dogroup(int sALIAS)
|
||||||
*/
|
*/
|
||||||
if (c == DO)
|
if (c == DO)
|
||||||
c = DONE;
|
c = DONE;
|
||||||
else if (c == ord('{'))
|
else if ((unsigned int)c == ORD('{'))
|
||||||
c = ord('}');
|
c = ORD('}');
|
||||||
else
|
else
|
||||||
syntaxerr(NULL);
|
syntaxerr(NULL);
|
||||||
list = c_list(sALIAS, true);
|
list = c_list(sALIAS, true);
|
||||||
|
@ -610,8 +614,8 @@ caselist(int sALIAS)
|
||||||
/* A {...} can be used instead of in...esac for case statements */
|
/* A {...} can be used instead of in...esac for case statements */
|
||||||
if (c == IN)
|
if (c == IN)
|
||||||
c = ESAC;
|
c = ESAC;
|
||||||
else if (c == ord('{'))
|
else if ((unsigned int)c == ORD('{'))
|
||||||
c = ord('}');
|
c = ORD('}');
|
||||||
else
|
else
|
||||||
syntaxerr(NULL);
|
syntaxerr(NULL);
|
||||||
t = tl = NULL;
|
t = tl = NULL;
|
||||||
|
@ -636,18 +640,17 @@ casepart(int endtok, int sALIAS)
|
||||||
XPinit(ptns, 16);
|
XPinit(ptns, 16);
|
||||||
t = newtp(TPAT);
|
t = newtp(TPAT);
|
||||||
/* no ALIAS here */
|
/* no ALIAS here */
|
||||||
if (token(CONTIN | KEYWORD) != ord('('))
|
if ((unsigned int)token(CONTIN | KEYWORD) != ORD('('))
|
||||||
REJECT;
|
REJECT;
|
||||||
do {
|
do {
|
||||||
switch (token(0)) {
|
switch (token(0)) {
|
||||||
case LWORD:
|
case LWORD:
|
||||||
break;
|
break;
|
||||||
case ord('}'):
|
case ORD('}'):
|
||||||
case ESAC:
|
case ESAC:
|
||||||
if (symbol != endtok) {
|
if (symbol != endtok) {
|
||||||
strdupx(yylval.cp,
|
strdupx(yylval.cp, (unsigned int)symbol ==
|
||||||
symbol == ord('}') ? Tcbrace : Tesac,
|
ORD('}') ? Tcbrace : Tesac, ATEMP);
|
||||||
ATEMP);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
|
@ -659,23 +662,23 @@ casepart(int endtok, int sALIAS)
|
||||||
REJECT;
|
REJECT;
|
||||||
XPput(ptns, NULL);
|
XPput(ptns, NULL);
|
||||||
t->vars = (char **)XPclose(ptns);
|
t->vars = (char **)XPclose(ptns);
|
||||||
musthave(ord(')'), 0);
|
musthave(ORD(')'), 0);
|
||||||
|
|
||||||
t->left = c_list(sALIAS, true);
|
t->left = c_list(sALIAS, true);
|
||||||
|
|
||||||
/* initialise to default for ;; or omitted */
|
/* initialise to default for ;; or omitted */
|
||||||
t->u.charflag = ord(';');
|
t->u.charflag = ORD(';');
|
||||||
/* SUSv4 requires the ;; except in the last casepart */
|
/* SUSv4 requires the ;; except in the last casepart */
|
||||||
if ((tpeek(CONTIN|KEYWORD|sALIAS)) != endtok)
|
if ((tpeek(CONTIN|KEYWORD|sALIAS)) != endtok)
|
||||||
switch (symbol) {
|
switch (symbol) {
|
||||||
default:
|
default:
|
||||||
syntaxerr(NULL);
|
syntaxerr(NULL);
|
||||||
case BRKEV:
|
case BRKEV:
|
||||||
t->u.charflag = ord('|');
|
t->u.charflag = ORD('|');
|
||||||
if (0)
|
if (0)
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case BRKFT:
|
case BRKFT:
|
||||||
t->u.charflag = ord('&');
|
t->u.charflag = ORD('&');
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case BREAK:
|
case BREAK:
|
||||||
/* initialised above, but we need to eat the token */
|
/* initialised above, but we need to eat the token */
|
||||||
|
@ -711,14 +714,14 @@ function_body(char *name, int sALIAS,
|
||||||
* only accepts an open-brace.
|
* only accepts an open-brace.
|
||||||
*/
|
*/
|
||||||
if (ksh_func) {
|
if (ksh_func) {
|
||||||
if (tpeek(CONTIN|KEYWORD|sALIAS) == ord('(' /*)*/)) {
|
if ((unsigned int)tpeek(CONTIN|KEYWORD|sALIAS) == ORD('(' /*)*/)) {
|
||||||
/* function foo () { //}*/
|
/* function foo () { //}*/
|
||||||
ACCEPT;
|
ACCEPT;
|
||||||
musthave(ord(/*(*/ ')'), 0);
|
musthave(ORD(/*(*/ ')'), 0);
|
||||||
/* degrade to POSIX function */
|
/* degrade to POSIX function */
|
||||||
ksh_func = false;
|
ksh_func = false;
|
||||||
}
|
}
|
||||||
musthave(ord('{' /*}*/), CONTIN|KEYWORD|sALIAS);
|
musthave(ORD('{' /*}*/), CONTIN|KEYWORD|sALIAS);
|
||||||
REJECT;
|
REJECT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -810,8 +813,8 @@ static const struct tokeninfo {
|
||||||
{ "in", IN, true },
|
{ "in", IN, true },
|
||||||
{ Tfunction, FUNCTION, true },
|
{ Tfunction, FUNCTION, true },
|
||||||
{ Ttime, TIME, true },
|
{ Ttime, TIME, true },
|
||||||
{ "{", ord('{'), true },
|
{ "{", ORD('{'), true },
|
||||||
{ Tcbrace, ord('}'), true },
|
{ Tcbrace, ORD('}'), true },
|
||||||
{ "!", BANG, true },
|
{ "!", BANG, true },
|
||||||
{ "[[", DBRACKET, true },
|
{ "[[", DBRACKET, true },
|
||||||
/* Lexical tokens (0[EOF], LWORD and REDIR handled specially) */
|
/* Lexical tokens (0[EOF], LWORD and REDIR handled specially) */
|
||||||
|
@ -823,7 +826,7 @@ static const struct tokeninfo {
|
||||||
{ "((", MDPAREN, false },
|
{ "((", MDPAREN, false },
|
||||||
{ "|&", COPROC, false },
|
{ "|&", COPROC, false },
|
||||||
/* and some special cases... */
|
/* and some special cases... */
|
||||||
{ "newline", ord('\n'), false },
|
{ "newline", ORD('\n'), false },
|
||||||
{ NULL, 0, false }
|
{ NULL, 0, false }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -998,9 +1001,9 @@ dbtestp_isa(Test_env *te, Test_meta meta)
|
||||||
ret = (uqword && !strcmp(yylval.cp,
|
ret = (uqword && !strcmp(yylval.cp,
|
||||||
dbtest_tokens[(int)TM_NOT])) ? TO_NONNULL : TO_NONOP;
|
dbtest_tokens[(int)TM_NOT])) ? TO_NONNULL : TO_NONOP;
|
||||||
else if (meta == TM_OPAREN)
|
else if (meta == TM_OPAREN)
|
||||||
ret = c == ord('(') /*)*/ ? TO_NONNULL : TO_NONOP;
|
ret = (unsigned int)c == ORD('(') /*)*/ ? TO_NONNULL : TO_NONOP;
|
||||||
else if (meta == TM_CPAREN)
|
else if (meta == TM_CPAREN)
|
||||||
ret = c == /*(*/ ord(')') ? TO_NONNULL : TO_NONOP;
|
ret = (unsigned int)c == /*(*/ ORD(')') ? TO_NONNULL : TO_NONOP;
|
||||||
else if (meta == TM_UNOP || meta == TM_BINOP) {
|
else if (meta == TM_UNOP || meta == TM_BINOP) {
|
||||||
if (meta == TM_BINOP && c == REDIR &&
|
if (meta == TM_BINOP && c == REDIR &&
|
||||||
(yylval.iop->ioflag == IOREAD ||
|
(yylval.iop->ioflag == IOREAD ||
|
||||||
|
@ -1131,14 +1134,14 @@ yyrecursive(int subtype)
|
||||||
struct op *t;
|
struct op *t;
|
||||||
char *cp;
|
char *cp;
|
||||||
struct yyrecursive_state *ys;
|
struct yyrecursive_state *ys;
|
||||||
int stok, etok;
|
unsigned int stok, etok;
|
||||||
|
|
||||||
if (subtype != COMSUB) {
|
if (subtype != COMSUB) {
|
||||||
stok = ord('{');
|
stok = ORD('{');
|
||||||
etok = ord('}');
|
etok = ORD('}');
|
||||||
} else {
|
} else {
|
||||||
stok = ord('(');
|
stok = ORD('(');
|
||||||
etok = ord(')');
|
etok = ORD(')');
|
||||||
}
|
}
|
||||||
|
|
||||||
ys = alloc(sizeof(struct yyrecursive_state), ATEMP);
|
ys = alloc(sizeof(struct yyrecursive_state), ATEMP);
|
||||||
|
|
65
src/tree.c
65
src/tree.c
|
@ -23,7 +23,7 @@
|
||||||
|
|
||||||
#include "sh.h"
|
#include "sh.h"
|
||||||
|
|
||||||
__RCSID("$MirOS: src/bin/mksh/tree.c,v 1.93 2017/05/05 22:53:32 tg Exp $");
|
__RCSID("$MirOS: src/bin/mksh/tree.c,v 1.95 2018/01/14 00:03:05 tg Exp $");
|
||||||
|
|
||||||
#define INDENT 8
|
#define INDENT 8
|
||||||
|
|
||||||
|
@ -329,7 +329,7 @@ wdvarput(struct shf *shf, const char *wp, int quotelevel, int opmode)
|
||||||
case EOS:
|
case EOS:
|
||||||
return (--wp);
|
return (--wp);
|
||||||
case ADELIM:
|
case ADELIM:
|
||||||
if (ord(*wp) == ord(/*{*/ '}')) {
|
if (ord(*wp) == ORD(/*{*/ '}')) {
|
||||||
++wp;
|
++wp;
|
||||||
goto wdvarput_csubst;
|
goto wdvarput_csubst;
|
||||||
}
|
}
|
||||||
|
@ -342,21 +342,21 @@ wdvarput(struct shf *shf, const char *wp, int quotelevel, int opmode)
|
||||||
c = ord(*wp++);
|
c = ord(*wp++);
|
||||||
if (opmode & WDS_TPUTS)
|
if (opmode & WDS_TPUTS)
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case ord('\n'):
|
case ORD('\n'):
|
||||||
if (quotelevel == 0) {
|
if (quotelevel == 0) {
|
||||||
c = ord('\'');
|
c = ORD('\'');
|
||||||
shf_putc(c, shf);
|
shf_putc(c, shf);
|
||||||
shf_putc(ord('\n'), shf);
|
shf_putc(ORD('\n'), shf);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (quotelevel == 0)
|
if (quotelevel == 0)
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case ord('"'):
|
case ORD('"'):
|
||||||
case ord('`'):
|
case ORD('`'):
|
||||||
case ord('$'):
|
case ORD('$'):
|
||||||
case ord('\\'):
|
case ORD('\\'):
|
||||||
shf_putc(ord('\\'), shf);
|
shf_putc(ORD('\\'), shf);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
shf_putc(c, shf);
|
shf_putc(c, shf);
|
||||||
|
@ -365,7 +365,7 @@ wdvarput(struct shf *shf, const char *wp, int quotelevel, int opmode)
|
||||||
case COMSUB:
|
case COMSUB:
|
||||||
shf_puts("$(", shf);
|
shf_puts("$(", shf);
|
||||||
cs = ")";
|
cs = ")";
|
||||||
if (ord(*wp) == ord('(' /*)*/))
|
if (ord(*wp) == ORD('(' /*)*/))
|
||||||
shf_putc(' ', shf);
|
shf_putc(' ', shf);
|
||||||
pSUB:
|
pSUB:
|
||||||
while ((c = *wp++) != 0)
|
while ((c = *wp++) != 0)
|
||||||
|
@ -374,11 +374,11 @@ wdvarput(struct shf *shf, const char *wp, int quotelevel, int opmode)
|
||||||
break;
|
break;
|
||||||
case FUNASUB:
|
case FUNASUB:
|
||||||
case FUNSUB:
|
case FUNSUB:
|
||||||
c = ord(' ');
|
c = ORD(' ');
|
||||||
if (0)
|
if (0)
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case VALSUB:
|
case VALSUB:
|
||||||
c = ord('|');
|
c = ORD('|');
|
||||||
shf_putc('$', shf);
|
shf_putc('$', shf);
|
||||||
shf_putc('{', shf);
|
shf_putc('{', shf);
|
||||||
shf_putc(c, shf);
|
shf_putc(c, shf);
|
||||||
|
@ -403,14 +403,14 @@ wdvarput(struct shf *shf, const char *wp, int quotelevel, int opmode)
|
||||||
break;
|
break;
|
||||||
case OSUBST:
|
case OSUBST:
|
||||||
shf_putc('$', shf);
|
shf_putc('$', shf);
|
||||||
if (ord(*wp++) == ord('{'))
|
if (ord(*wp++) == ORD('{'))
|
||||||
shf_putc('{', shf);
|
shf_putc('{', shf);
|
||||||
while ((c = *wp++) != 0)
|
while ((c = *wp++) != 0)
|
||||||
shf_putc(c, shf);
|
shf_putc(c, shf);
|
||||||
wp = wdvarput(shf, wp, 0, opmode);
|
wp = wdvarput(shf, wp, 0, opmode);
|
||||||
break;
|
break;
|
||||||
case CSUBST:
|
case CSUBST:
|
||||||
if (ord(*wp++) == ord('}')) {
|
if (ord(*wp++) == ORD('}')) {
|
||||||
wdvarput_csubst:
|
wdvarput_csubst:
|
||||||
shf_putc('}', shf);
|
shf_putc('}', shf);
|
||||||
}
|
}
|
||||||
|
@ -420,11 +420,11 @@ wdvarput(struct shf *shf, const char *wp, int quotelevel, int opmode)
|
||||||
shf_putc('(', shf);
|
shf_putc('(', shf);
|
||||||
break;
|
break;
|
||||||
case SPAT:
|
case SPAT:
|
||||||
c = ord('|');
|
c = ORD('|');
|
||||||
if (0)
|
if (0)
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case CPAT:
|
case CPAT:
|
||||||
c = ord(/*(*/ ')');
|
c = ORD(/*(*/ ')');
|
||||||
shf_putc(c, shf);
|
shf_putc(c, shf);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -470,36 +470,37 @@ vfptreef(struct shf *shf, int indent, const char *fmt, va_list va)
|
||||||
while ((c = ord(*fmt++))) {
|
while ((c = ord(*fmt++))) {
|
||||||
if (c == '%') {
|
if (c == '%') {
|
||||||
switch ((c = ord(*fmt++))) {
|
switch ((c = ord(*fmt++))) {
|
||||||
case ord('c'):
|
case ORD('c'):
|
||||||
/* character (octet, probably) */
|
/* character (octet, probably) */
|
||||||
shf_putchar(va_arg(va, int), shf);
|
shf_putchar(va_arg(va, int), shf);
|
||||||
break;
|
break;
|
||||||
case ord('s'):
|
case ORD('s'):
|
||||||
/* string */
|
/* string */
|
||||||
shf_puts(va_arg(va, char *), shf);
|
shf_puts(va_arg(va, char *), shf);
|
||||||
break;
|
break;
|
||||||
case ord('S'):
|
case ORD('S'):
|
||||||
/* word */
|
/* word */
|
||||||
wdvarput(shf, va_arg(va, char *), 0, WDS_TPUTS);
|
wdvarput(shf, va_arg(va, char *), 0, WDS_TPUTS);
|
||||||
break;
|
break;
|
||||||
case ord('d'):
|
case ORD('d'):
|
||||||
/* signed decimal */
|
/* signed decimal */
|
||||||
shf_fprintf(shf, Tf_d, va_arg(va, int));
|
shf_fprintf(shf, Tf_d, va_arg(va, int));
|
||||||
break;
|
break;
|
||||||
case ord('u'):
|
case ORD('u'):
|
||||||
/* unsigned decimal */
|
/* unsigned decimal */
|
||||||
shf_fprintf(shf, "%u", va_arg(va, unsigned int));
|
shf_fprintf(shf, "%u", va_arg(va, unsigned int));
|
||||||
break;
|
break;
|
||||||
case ord('T'):
|
case ORD('T'):
|
||||||
/* format tree */
|
/* format tree */
|
||||||
ptree(va_arg(va, struct op *), indent, shf);
|
ptree(va_arg(va, struct op *), indent, shf);
|
||||||
goto dont_trash_prevent_semicolon;
|
goto dont_trash_prevent_semicolon;
|
||||||
case ord(';'):
|
case ORD(';'):
|
||||||
/* newline or ; */
|
/* newline or ; */
|
||||||
case ord('N'):
|
case ORD('N'):
|
||||||
/* newline or space */
|
/* newline or space */
|
||||||
if (shf->flags & SHF_STRING) {
|
if (shf->flags & SHF_STRING) {
|
||||||
if (c == ord(';') && !prevent_semicolon)
|
if ((unsigned int)c == ORD(';') &&
|
||||||
|
!prevent_semicolon)
|
||||||
shf_putc(';', shf);
|
shf_putc(';', shf);
|
||||||
shf_putc(' ', shf);
|
shf_putc(' ', shf);
|
||||||
} else {
|
} else {
|
||||||
|
@ -515,7 +516,7 @@ vfptreef(struct shf *shf, int indent, const char *fmt, va_list va)
|
||||||
shf_putc(' ', shf);
|
shf_putc(' ', shf);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ord('R'):
|
case ORD('R'):
|
||||||
/* I/O redirection */
|
/* I/O redirection */
|
||||||
pioact(shf, va_arg(va, struct ioword *));
|
pioact(shf, va_arg(va, struct ioword *));
|
||||||
break;
|
break;
|
||||||
|
@ -613,7 +614,7 @@ wdscan(const char *wp, int c)
|
||||||
case ADELIM:
|
case ADELIM:
|
||||||
if (c == ADELIM && nest == 0)
|
if (c == ADELIM && nest == 0)
|
||||||
return (wp + 1);
|
return (wp + 1);
|
||||||
if (ord(*wp) == ord(/*{*/ '}'))
|
if (ord(*wp) == ORD(/*{*/ '}'))
|
||||||
goto wdscan_csubst;
|
goto wdscan_csubst;
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case CHAR:
|
case CHAR:
|
||||||
|
@ -808,7 +809,7 @@ vistree(char *dst, size_t sz, struct op *t)
|
||||||
} else if (UTFMODE && rtt2asc(c) > 0x7F) {
|
} else if (UTFMODE && rtt2asc(c) > 0x7F) {
|
||||||
/* better not try to display broken multibyte chars */
|
/* better not try to display broken multibyte chars */
|
||||||
/* also go easy on the Unicode: no U+FFFD here */
|
/* also go easy on the Unicode: no U+FFFD here */
|
||||||
c = ord('?');
|
c = ORD('?');
|
||||||
}
|
}
|
||||||
*dst++ = c;
|
*dst++ = c;
|
||||||
goto vist_loop;
|
goto vist_loop;
|
||||||
|
@ -842,7 +843,7 @@ dumpwdvar_i(struct shf *shf, const char *wp, int quotelevel)
|
||||||
shf_puts("EOS", shf);
|
shf_puts("EOS", shf);
|
||||||
return (--wp);
|
return (--wp);
|
||||||
case ADELIM:
|
case ADELIM:
|
||||||
if (ord(*wp) == ord(/*{*/ '}')) {
|
if (ord(*wp) == ORD(/*{*/ '}')) {
|
||||||
shf_puts(/*{*/ "]ADELIM(})", shf);
|
shf_puts(/*{*/ "]ADELIM(})", shf);
|
||||||
return (wp + 1);
|
return (wp + 1);
|
||||||
}
|
}
|
||||||
|
@ -856,8 +857,8 @@ dumpwdvar_i(struct shf *shf, const char *wp, int quotelevel)
|
||||||
case QCHAR:
|
case QCHAR:
|
||||||
shf_puts("QCHAR<", shf);
|
shf_puts("QCHAR<", shf);
|
||||||
c = ord(*wp++);
|
c = ord(*wp++);
|
||||||
if (quotelevel == 0 || c == ord('"') ||
|
if (quotelevel == 0 || c == ORD('"') ||
|
||||||
c == ord('\\') || ctype(c, C_DOLAR | C_GRAVE))
|
c == ORD('\\') || ctype(c, C_DOLAR | C_GRAVE))
|
||||||
shf_putc('\\', shf);
|
shf_putc('\\', shf);
|
||||||
dumpchar(shf, c);
|
dumpchar(shf, c);
|
||||||
goto closeandout;
|
goto closeandout;
|
||||||
|
|
82
src/var.c
82
src/var.c
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
|
* Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
|
||||||
* 2011, 2012, 2013, 2014, 2015, 2016, 2017
|
* 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018
|
||||||
* mirabilos <m@mirbsd.org>
|
* mirabilos <m@mirbsd.org>
|
||||||
*
|
*
|
||||||
* Provided that these terms and disclaimer and all copyright notices
|
* Provided that these terms and disclaimer and all copyright notices
|
||||||
|
@ -28,7 +28,7 @@
|
||||||
#include <sys/sysctl.h>
|
#include <sys/sysctl.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
__RCSID("$MirOS: src/bin/mksh/var.c,v 1.220 2017/07/26 23:02:28 tg Exp $");
|
__RCSID("$MirOS: src/bin/mksh/var.c,v 1.223 2018/01/13 23:55:15 tg Exp $");
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Variables
|
* Variables
|
||||||
|
@ -136,7 +136,7 @@ initvar(void)
|
||||||
struct tbl *tp;
|
struct tbl *tp;
|
||||||
|
|
||||||
ktinit(APERM, &specials,
|
ktinit(APERM, &specials,
|
||||||
/* currently 18 specials: 75% of 32 = 2^5 */
|
/* currently 21 specials: 75% of 32 = 2^5 */
|
||||||
5);
|
5);
|
||||||
while (i < V_MAX - 1) {
|
while (i < V_MAX - 1) {
|
||||||
tp = ktenter(&specials, initvar_names[i],
|
tp = ktenter(&specials, initvar_names[i],
|
||||||
|
@ -204,7 +204,7 @@ array_index_calc(const char *n, bool *arrayp, uint32_t *valp)
|
||||||
}
|
}
|
||||||
innermost_refflag = SRF_NOP;
|
innermost_refflag = SRF_NOP;
|
||||||
|
|
||||||
if (p != n && ord(*p) == ord('[') && (len = array_ref_len(p))) {
|
if (p != n && ord(*p) == ORD('[') && (len = array_ref_len(p))) {
|
||||||
char *sub, *tmp;
|
char *sub, *tmp;
|
||||||
mksh_ari_t rval;
|
mksh_ari_t rval;
|
||||||
|
|
||||||
|
@ -780,7 +780,7 @@ typeset(const char *var, uint32_t set, uint32_t clr, int field, int base)
|
||||||
/* no variable name given */
|
/* no variable name given */
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
if (ord(*val) == ord('[')) {
|
if (ord(*val) == ORD('[')) {
|
||||||
if (new_refflag != SRF_NOP)
|
if (new_refflag != SRF_NOP)
|
||||||
errorf(Tf_sD_s, var,
|
errorf(Tf_sD_s, var,
|
||||||
"reference variable can't be an array");
|
"reference variable can't be an array");
|
||||||
|
@ -803,13 +803,13 @@ typeset(const char *var, uint32_t set, uint32_t clr, int field, int base)
|
||||||
}
|
}
|
||||||
val += len;
|
val += len;
|
||||||
}
|
}
|
||||||
if (ord(val[0]) == ord('=')) {
|
if (ord(val[0]) == ORD('=')) {
|
||||||
strndupx(tvar, var, val - var, ATEMP);
|
strndupx(tvar, var, val - var, ATEMP);
|
||||||
++val;
|
++val;
|
||||||
} else if (set & IMPORT) {
|
} else if (set & IMPORT) {
|
||||||
/* environment invalid variable name or no assignment */
|
/* environment invalid variable name or no assignment */
|
||||||
return (NULL);
|
return (NULL);
|
||||||
} else if (ord(val[0]) == ord('+') && ord(val[1]) == ord('=')) {
|
} else if (ord(val[0]) == ORD('+') && ord(val[1]) == ORD('=')) {
|
||||||
strndupx(tvar, var, val - var, ATEMP);
|
strndupx(tvar, var, val - var, ATEMP);
|
||||||
val += 2;
|
val += 2;
|
||||||
vappend = true;
|
vappend = true;
|
||||||
|
@ -822,9 +822,9 @@ typeset(const char *var, uint32_t set, uint32_t clr, int field, int base)
|
||||||
val = NULL;
|
val = NULL;
|
||||||
/* handle foo[*] => foo (whole array) mapping for R39b */
|
/* handle foo[*] => foo (whole array) mapping for R39b */
|
||||||
len = strlen(tvar);
|
len = strlen(tvar);
|
||||||
if (len > 3 && ord(tvar[len - 3]) == ord('[') &&
|
if (len > 3 && ord(tvar[len - 3]) == ORD('[') &&
|
||||||
ord(tvar[len - 2]) == ord('*') &&
|
ord(tvar[len - 2]) == ORD('*') &&
|
||||||
ord(tvar[len - 1]) == ord(']'))
|
ord(tvar[len - 1]) == ORD(']'))
|
||||||
tvar[len - 3] = '\0';
|
tvar[len - 3] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -861,7 +861,7 @@ typeset(const char *var, uint32_t set, uint32_t clr, int field, int base)
|
||||||
nameref_empty:
|
nameref_empty:
|
||||||
errorf(Tf_sD_s, var, "empty nameref target");
|
errorf(Tf_sD_s, var, "empty nameref target");
|
||||||
}
|
}
|
||||||
len = (ord(*ccp) == ord('[')) ? array_ref_len(ccp) : 0;
|
len = (ord(*ccp) == ORD('[')) ? array_ref_len(ccp) : 0;
|
||||||
if (ccp[len]) {
|
if (ccp[len]) {
|
||||||
/*
|
/*
|
||||||
* works for cases "no array", "valid array with
|
* works for cases "no array", "valid array with
|
||||||
|
@ -1071,7 +1071,7 @@ skip_varname(const char *s, bool aok)
|
||||||
do {
|
do {
|
||||||
++s;
|
++s;
|
||||||
} while (ctype(*s, C_ALNUX));
|
} while (ctype(*s, C_ALNUX));
|
||||||
if (aok && ord(*s) == ord('[') && (alen = array_ref_len(s)))
|
if (aok && ord(*s) == ORD('[') && (alen = array_ref_len(s)))
|
||||||
s += alen;
|
s += alen;
|
||||||
}
|
}
|
||||||
return (s);
|
return (s);
|
||||||
|
@ -1087,7 +1087,7 @@ skip_wdvarname(const char *s,
|
||||||
do {
|
do {
|
||||||
s += 2;
|
s += 2;
|
||||||
} while (s[0] == CHAR && ctype(s[1], C_ALNUX));
|
} while (s[0] == CHAR && ctype(s[1], C_ALNUX));
|
||||||
if (aok && s[0] == CHAR && ord(s[1]) == ord('[')) {
|
if (aok && s[0] == CHAR && ord(s[1]) == ORD('[')) {
|
||||||
/* skip possible array de-reference */
|
/* skip possible array de-reference */
|
||||||
const char *p = s;
|
const char *p = s;
|
||||||
char c;
|
char c;
|
||||||
|
@ -1098,9 +1098,9 @@ skip_wdvarname(const char *s,
|
||||||
break;
|
break;
|
||||||
c = p[1];
|
c = p[1];
|
||||||
p += 2;
|
p += 2;
|
||||||
if (ord(c) == ord('['))
|
if (ord(c) == ORD('['))
|
||||||
depth++;
|
depth++;
|
||||||
else if (ord(c) == ord(']') && --depth == 0) {
|
else if (ord(c) == ORD(']') && --depth == 0) {
|
||||||
s = p;
|
s = p;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1294,9 +1294,29 @@ setspec(struct tbl *vp)
|
||||||
{
|
{
|
||||||
mksh_ari_u num;
|
mksh_ari_u num;
|
||||||
char *s;
|
char *s;
|
||||||
int st;
|
int st = special(vp->name);
|
||||||
|
|
||||||
switch ((st = special(vp->name))) {
|
#ifdef MKSH_DOSPATH
|
||||||
|
switch (st) {
|
||||||
|
case V_PATH:
|
||||||
|
case V_TMPDIR:
|
||||||
|
#ifdef __OS2__
|
||||||
|
case V_BEGINLIBPATH:
|
||||||
|
case V_ENDLIBPATH:
|
||||||
|
#endif
|
||||||
|
/* convert backslashes to slashes for convenience */
|
||||||
|
if (!(vp->flag&INTEGER)) {
|
||||||
|
s = str_val(vp);
|
||||||
|
do {
|
||||||
|
if (*s == ORD('\\'))
|
||||||
|
*s = '/';
|
||||||
|
} while (*s++);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
switch (st) {
|
||||||
#ifdef __OS2__
|
#ifdef __OS2__
|
||||||
case V_BEGINLIBPATH:
|
case V_BEGINLIBPATH:
|
||||||
case V_ENDLIBPATH:
|
case V_ENDLIBPATH:
|
||||||
|
@ -1366,6 +1386,13 @@ setspec(struct tbl *vp)
|
||||||
}
|
}
|
||||||
vp->flag |= SPECIAL;
|
vp->flag |= SPECIAL;
|
||||||
break;
|
break;
|
||||||
|
#ifdef MKSH_EARLY_LOCALE_TRACKING
|
||||||
|
case V_LANG:
|
||||||
|
case V_LC_ALL:
|
||||||
|
case V_LC_CTYPE:
|
||||||
|
recheck_ctype();
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
/* do nothing, do not touch vp at all */
|
/* do nothing, do not touch vp at all */
|
||||||
return;
|
return;
|
||||||
|
@ -1465,6 +1492,13 @@ unsetspec(struct tbl *vp)
|
||||||
/* AT&T ksh leaves previous value in place */
|
/* AT&T ksh leaves previous value in place */
|
||||||
unspecial(vp->name);
|
unspecial(vp->name);
|
||||||
break;
|
break;
|
||||||
|
#ifdef MKSH_EARLY_LOCALE_TRACKING
|
||||||
|
case V_LANG:
|
||||||
|
case V_LC_ALL:
|
||||||
|
case V_LC_CTYPE:
|
||||||
|
recheck_ctype();
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1528,8 +1562,8 @@ array_ref_len(const char *cp)
|
||||||
char c;
|
char c;
|
||||||
int depth = 0;
|
int depth = 0;
|
||||||
|
|
||||||
while ((c = *s++) && (ord(c) != ord(']') || --depth))
|
while ((c = *s++) && (ord(c) != ORD(']') || --depth))
|
||||||
if (ord(c) == ord('['))
|
if (ord(c) == ORD('['))
|
||||||
depth++;
|
depth++;
|
||||||
if (!c)
|
if (!c)
|
||||||
return (0);
|
return (0);
|
||||||
|
@ -1601,18 +1635,18 @@ set_array(const char *var, bool reset, const char **vals)
|
||||||
}
|
}
|
||||||
while ((ccp = vals[i])) {
|
while ((ccp = vals[i])) {
|
||||||
#if 0 /* temporarily taken out due to regression */
|
#if 0 /* temporarily taken out due to regression */
|
||||||
if (ord(*ccp) == ord('[')) {
|
if (ord(*ccp) == ORD('[')) {
|
||||||
int level = 0;
|
int level = 0;
|
||||||
|
|
||||||
while (*ccp) {
|
while (*ccp) {
|
||||||
if (ord(*ccp) == ord(']') && --level == 0)
|
if (ord(*ccp) == ORD(']') && --level == 0)
|
||||||
break;
|
break;
|
||||||
if (ord(*ccp) == ord('['))
|
if (ord(*ccp) == ORD('['))
|
||||||
++level;
|
++level;
|
||||||
++ccp;
|
++ccp;
|
||||||
}
|
}
|
||||||
if (ord(*ccp) == ord(']') && level == 0 &&
|
if (ord(*ccp) == ORD(']') && level == 0 &&
|
||||||
ord(ccp[1]) == ord('=')) {
|
ord(ccp[1]) == ORD('=')) {
|
||||||
strndupx(cp, vals[i] + 1, ccp - (vals[i] + 1),
|
strndupx(cp, vals[i] + 1, ccp - (vals[i] + 1),
|
||||||
ATEMP);
|
ATEMP);
|
||||||
evaluate(substitute(cp, 0), (mksh_ari_t *)&j,
|
evaluate(substitute(cp, 0), (mksh_ari_t *)&j,
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 2009, 2011, 2012, 2016
|
* Copyright (c) 2009, 2011, 2012, 2016, 2018
|
||||||
* mirabilos <m@mirbsd.org>
|
* mirabilos <m@mirbsd.org>
|
||||||
*
|
*
|
||||||
* Provided that these terms and disclaimer and all copyright notices
|
* Provided that these terms and disclaimer and all copyright notices
|
||||||
|
@ -19,7 +19,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(VARSPEC_DEFNS)
|
#if defined(VARSPEC_DEFNS)
|
||||||
__RCSID("$MirOS: src/bin/mksh/var_spec.h,v 1.10 2016/11/11 23:31:39 tg Exp $");
|
__RCSID("$MirOS: src/bin/mksh/var_spec.h,v 1.11 2018/01/13 21:38:10 tg Exp $");
|
||||||
#define FN(name) /* nothing */
|
#define FN(name) /* nothing */
|
||||||
#elif defined(VARSPEC_ENUMS)
|
#elif defined(VARSPEC_ENUMS)
|
||||||
#define FN(name) V_##name,
|
#define FN(name) V_##name,
|
||||||
|
@ -53,6 +53,11 @@ FN(HISTFILE)
|
||||||
#endif
|
#endif
|
||||||
FN(HISTSIZE)
|
FN(HISTSIZE)
|
||||||
FN(IFS)
|
FN(IFS)
|
||||||
|
#ifdef MKSH_EARLY_LOCALE_TRACKING
|
||||||
|
FN(LANG)
|
||||||
|
FN(LC_ALL)
|
||||||
|
FN(LC_CTYPE)
|
||||||
|
#endif
|
||||||
#ifdef __OS2__
|
#ifdef __OS2__
|
||||||
FN(LIBPATHSTRICT)
|
FN(LIBPATHSTRICT)
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue