From 91b5d4b3ada98df157ea0fed146358c444024472 Mon Sep 17 00:00:00 2001 From: tg Date: Wed, 24 Aug 2016 19:35:26 +0000 Subject: [PATCH 01/31] =?UTF-8?q?remove=20all=20mentions=20of=20=E2=80=9Ct?= =?UTF-8?q?he=20null=20string=E2=80=9D,=20it=E2=80=99s=20an=20empty=20stri?= =?UTF-8?q?ng=20(in=20most=20cases),=20or=20an=20unset=20parameter=20(in?= =?UTF-8?q?=20some=20cases)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mksh.1 | 60 ++++++++++++++++++++-------------------------------------- 1 file changed, 20 insertions(+), 40 deletions(-) diff --git a/mksh.1 b/mksh.1 index 596fa3c..f9d234a 100644 --- a/mksh.1 +++ b/mksh.1 @@ -1,4 +1,4 @@ -.\" $MirOS: src/bin/mksh/mksh.1,v 1.413 2016/08/10 18:20:05 tg Exp $ +.\" $MirOS: src/bin/mksh/mksh.1,v 1.414 2016/08/24 19:35:26 tg Exp $ .\" $OpenBSD: ksh.1,v 1.160 2015/07/04 13:27:04 feinerer Exp $ .\"- .\" Copyright © 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, @@ -76,7 +76,7 @@ .\" with -mandoc, it might implement .Mx itself, but we want to .\" use our own definition. And .Dd must come *first*, always. .\" -.Dd $Mdocdate: August 10 2016 $ +.Dd $Mdocdate: August 24 2016 $ .\" .\" Check which macro package we use, and do other -mdoc setup. .\" @@ -829,9 +829,7 @@ When .Ar list completes, the enumerated list is printed if .Ev REPLY -is -.Dv NULL , -the prompt is printed, and so on. +is empty, the prompt is printed, and so on. This process continues until an end-of-file is read, an interrupt is received, or a .Ic break @@ -1389,14 +1387,10 @@ and works equivalent to $* and $@ for positional parameters. If substitution is performed on a parameter (or an array parameter element) -that is not set, a null string is substituted unless the +that is not set, an empty string is substituted unless the .Ic nounset option -.Po -.Ic set Fl o Ic nounset -or -.Ic set Fl u -.Pc +.Pq Ic set Fl u is set, in which case an error occurs. .Pp Parameters can be assigned values in a number of ways. @@ -1476,8 +1470,7 @@ form of parameter substitution: .Sm on If .Ar name -is set and not -.Dv NULL , +is set and not empty, it is substituted; otherwise, .Ar word is substituted. @@ -1486,8 +1479,7 @@ is substituted. .Sm on If .Ar name -is set and not -.Dv NULL , +is set and not empty, .Ar word is substituted; otherwise, nothing is substituted. .Sm off @@ -1495,8 +1487,7 @@ is substituted; otherwise, nothing is substituted. .Sm on If .Ar name -is set and not -.Dv NULL , +is set and not empty, it is substituted; otherwise, it is assigned .Ar word and the resulting value of @@ -1507,8 +1498,7 @@ is substituted. .Sm on If .Ar name -is set and not -.Dv NULL , +is set and not empty, it is substituted; otherwise, .Ar word is printed on standard error (preceded by @@ -1524,7 +1514,7 @@ is omitted, the string is used instead. Currently a bug, if .Ar word -is a variable which expands to the null string, the +is a variable which expands to the empty string, the error message is also printed. .El .Pp @@ -1541,8 +1531,7 @@ In the above modifiers, the .Ql \&: can be omitted, in which case the conditions only depend on .Ar name -being set (as opposed to set and not -.Dv NULL ) . +being set (as opposed to set and not empty). If .Ar word is needed, parameter, command, arithmetic, and tilde substitution are performed @@ -1815,18 +1804,16 @@ by the first character of the .Ev IFS parameter (or the empty string if .Ev IFS -is -.Dv NULL ) . +is unset. .It Ev @ Same as .Ic $* , unless it is used inside double quotes, in which case a separate word is generated for each positional parameter. If there are no positional parameters, no word is generated. -.Ic $@ +.Ic \&"$@" can be used to access arguments, verbatim, without losing -.Dv NULL -arguments or splitting arguments with spaces. +empty arguments or splitting arguments with spaces (IFS, actually). .El .Pp The following parameters are set and/or used by the shell: @@ -2170,9 +2157,7 @@ You may want to set it to instead, to include timestamps. .It Ev PWD The current working directory. -May be unset or -.Dv NULL -if the shell doesn't know where it is. +May be unset or empty if the shell doesn't know where it is. .It Ev RANDOM Each time .Ev RANDOM @@ -2434,7 +2419,7 @@ the shell. Three exceptions to this are commands in pipelines, for which standard input and/or standard output are those set up by the pipeline, asynchronous commands created when job control is disabled, for which standard -input is initially set to be from +input is initially set to .Pa /dev/null , and commands for which any of the following redirections have been specified: .Bl -tag -width XXxxmarker @@ -3277,16 +3262,13 @@ If the parameter .Ev CDPATH is set, it lists the search path for the directory containing .Ar dir . -A -.Dv NULL -path means the current directory. +An unset or empty path means the current directory. If .Ar dir is found in any component of the .Ev CDPATH -search path other than the -.Dv NULL -path, the name of the new working directory will be written to standard output. +search path other than an unset or empty path, +the name of the new working directory will be written to standard output. If .Ar dir is missing, the home directory @@ -4668,9 +4650,7 @@ A common mistake is to use .Dq if \&[ $foo = bar \&] which fails if parameter .Dq foo -is -.Dv NULL -or unset, if it has embedded spaces (i.e.\& +is empty or unset, if it has embedded spaces (i.e.\& .Ev IFS octets), or if it is a unary operator like .Sq \&! From 35bd16ddfa3b1336e6ac049a6f0b3dee8ef149f6 Mon Sep 17 00:00:00 2001 From: tg Date: Wed, 24 Aug 2016 19:36:26 +0000 Subject: [PATCH 02/31] this bug has long been fixed --- mksh.1 | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/mksh.1 b/mksh.1 index f9d234a..59cefe9 100644 --- a/mksh.1 +++ b/mksh.1 @@ -1,4 +1,4 @@ -.\" $MirOS: src/bin/mksh/mksh.1,v 1.414 2016/08/24 19:35:26 tg Exp $ +.\" $MirOS: src/bin/mksh/mksh.1,v 1.415 2016/08/24 19:36:26 tg Exp $ .\" $OpenBSD: ksh.1,v 1.160 2015/07/04 13:27:04 feinerer Exp $ .\"- .\" Copyright © 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, @@ -1512,10 +1512,6 @@ If is omitted, the string .Dq parameter null or not set is used instead. -Currently a bug, if -.Ar word -is a variable which expands to the empty string, the -error message is also printed. .El .Pp Note that, for all of the above, From bb796ff785644e43c21a4b01ee9d570927d5cf51 Mon Sep 17 00:00:00 2001 From: tg Date: Wed, 24 Aug 2016 20:40:00 +0000 Subject: [PATCH 03/31] simplify manpage and code; streamline manpage formatting and Satzzeichen --- exec.c | 12 +- mksh.1 | 499 ++++++++++++++++++++++++++++----------------------------- 2 files changed, 252 insertions(+), 259 deletions(-) diff --git a/exec.c b/exec.c index e3149cd..6383924 100644 --- a/exec.c +++ b/exec.c @@ -23,7 +23,7 @@ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.179 2016/08/01 21:38:02 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.180 2016/08/24 20:40:00 tg Exp $"); #ifndef MKSH_DEFAULT_EXECSHELL #define MKSH_DEFAULT_EXECSHELL MKSH_UNIXROOT "/bin/sh" @@ -339,16 +339,14 @@ execute(struct op * volatile t, rv = execute(t->left, flags & XERROK, xerrok); } } else { - /* TSELECT */ - for (;;) { - if (!(ccp = do_selectargs(ap, is_first))) { - rv = 1; - break; - } + do_TSELECT: + if ((ccp = do_selectargs(ap, is_first))) { is_first = false; setstr(global(t->str), ccp, KSH_UNWIND_ERROR); execute(t->left, flags & XERROK, xerrok); + goto do_TSELECT; } + rv = 1; } break; } diff --git a/mksh.1 b/mksh.1 index 59cefe9..c86ccaf 100644 --- a/mksh.1 +++ b/mksh.1 @@ -1,4 +1,4 @@ -.\" $MirOS: src/bin/mksh/mksh.1,v 1.415 2016/08/24 19:36:26 tg Exp $ +.\" $MirOS: src/bin/mksh/mksh.1,v 1.416 2016/08/24 20:40:00 tg Exp $ .\" $OpenBSD: ksh.1,v 1.160 2015/07/04 13:27:04 feinerer Exp $ .\"- .\" Copyright © 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, @@ -300,10 +300,10 @@ option of the built-in command can't be used. .It Redirections that create files can't be used (i.e.\& -.Ql \*(Gt , -.Ql \*(Gt\*(Ba , -.Ql \*(Gt\*(Gt , -.Ql \*(Lt\*(Gt ) . +.Dq Li \*(Gt , +.Dq Li \*(Gt\*(Ba , +.Dq Li \*(Gt\*(Gt , +.Dq Li \*(Lt\*(Gt ) . .El .It Fl s The shell reads commands from standard input; all non-option arguments @@ -323,12 +323,12 @@ are attempted in order. Unless .Ar name begins with an exclamation mark -.Pq Sq \&! , +.Pq Ql \&! , this is done in a subshell and returns immediately. If .Ar name is a dash -.Pq Sq \&\- , +.Pq Ql \&\- , detach from controlling terminal (daemonise) instead. .El .Pp @@ -371,7 +371,7 @@ A non-privileged login shell processes the user profile next. A non-privileged interactive shell checks the value of the .Ev ENV parameter after subjecting it to parameter, command, arithmetic and tilde -.Pq Sq \*(TI +.Pq Ql \*(TI substitution; if unset or empty, the user mkshrc profile is processed; otherwise, if a file whose name is the substitution result exists, it is processed; non-existence is silently ignored. @@ -398,56 +398,56 @@ Aside from delimiting words, spaces and tabs are ignored, while newlines usually delimit commands. The meta-characters are used in building the following .Em tokens : -.Ql \*(Lt , -.Ql \*(Lt& , -.Ql \*(Lt\*(Lt , -.Ql \*(Lt\*(Lt\*(Lt , -.Ql \*(Gt , -.Ql \*(Gt& , -.Ql \*(Gt\*(Gt , -.Ql &\*(Gt , +.Dq Li \*(Lt , +.Dq Li \*(Lt& , +.Dq Li \*(Lt\*(Lt , +.Dq Li \*(Lt\*(Lt\*(Lt , +.Dq Li \*(Gt , +.Dq Li \*(Gt& , +.Dq Li \*(Gt\*(Gt , +.Dq Li &\*(Gt , etc. are used to specify redirections (see .Sx Input/output redirection below); -.Ql \*(Ba +.Dq Li \*(Ba is used to create pipelines; -.Ql \*(Ba& +.Dq Li \*(Ba& is used to create co-processes (see .Sx Co-processes below); -.Ql \&; +.Dq Li \&; is used to separate commands; -.Ql & +.Dq Li & is used to create asynchronous pipelines; -.Ql && +.Dq Li && and -.Ql \*(Ba\*(Ba +.Dq Li \*(Ba\*(Ba are used to specify conditional execution; -.Ql ;; , -.Ql ;&\& +.Dq Li \&;; , +.Dq Li \&;& and -.Ql ;\*(Ba\& +.Dq Li \&;\*(Ba are used in .Ic case statements; -.Ql \&(( .. )) +.Dq Li \&(( ... \&)) is used in arithmetic expressions; and lastly, -.Ql \&( .. \&) +.Dq Li \&( ... \&) is used to create subshells. .Pp Whitespace and meta-characters can be quoted individually using a backslash -.Pq Sq \e , +.Pq Ql \e , or in groups using double -.Pq Sq \&" +.Pq Ql \&" or single -.Pq Dq \*(aq +.Pq Dq Li \*(aq quotes. Note that the following characters are also treated specially by the shell and must be quoted if they are to represent themselves: .Ql \e , .Ql \&" , -.Ql \*(aq , +.Dq Li \*(aq , .Ql # , .Ql $ , .Ql \` , @@ -537,7 +537,7 @@ assignments is that of the last command substitution performed during the parameter assignment or 0 if there were no command substitutions. .Pp Commands can be chained together using the -.Ql \*(Ba +.Dq Li \*(Ba token to form pipelines, in which the standard output of each command but the last is piped (see .Xr pipe 2 ) @@ -553,7 +553,7 @@ where all but the last command were executed in subshells; see the .Ic read builtin's description for implications and workarounds. A pipeline may be prefixed by the -.Ql \&! +.Dq Li \&! reserved word which causes the exit status of the pipeline to be logically complemented: if the original status was 0, the complemented status will be 1; if the original status was not 0, the complemented status will be 0. @@ -561,12 +561,12 @@ if the original status was not 0, the complemented status will be 0. .Em Lists of commands can be created by separating pipelines by any of the following tokens: -.Ql && , -.Ql \*(Ba\*(Ba , -.Ql & , -.Ql \*(Ba& , +.Dq Li && , +.Dq Li \*(Ba\*(Ba , +.Dq Li & , +.Dq Li \*(Ba& , and -.Ql \&; . +.Dq Li \&; . The first two are for conditional execution: .Dq Ar cmd1 No && Ar cmd2 executes @@ -574,25 +574,25 @@ executes only if the exit status of .Ar cmd1 is zero; -.Ql \*(Ba\*(Ba +.Dq Li \*(Ba\*(Ba is the opposite \*(en .Ar cmd2 is executed only if the exit status of .Ar cmd1 is non-zero. -.Ql && +.Dq Li && and -.Ql \*(Ba\*(Ba +.Dq Li \*(Ba\*(Ba have equal precedence which is higher than that of -.Ql & , -.Ql \*(Ba& , +.Dq Li & , +.Dq Li \*(Ba& , and -.Ql \&; , +.Dq Li \&; , which also have equal precedence. Note that the -.Ql && +.Dq Li && and -.Ql \*(Ba\*(Ba +.Dq Li \*(Ba\*(Ba operators are .Qq left-associative . For example, both of these commands will print only @@ -603,7 +603,7 @@ $ true \*(Ba\*(Ba echo foo && echo bar .Ed .Pp The -.Ql & +.Dq Li & token causes the preceding command to be executed asynchronously; that is, the shell starts the command but does not wait for it to complete (the shell does keep track of the status of asynchronous commands; see @@ -618,20 +618,20 @@ ignored and with input redirected from .Pa /dev/null (however, redirections specified in the asynchronous command have precedence). The -.Ql \*(Ba& +.Dq Li \*(Ba& operator starts a co-process which is a special kind of asynchronous process (see .Sx Co-processes below). Note that a command must follow the -.Ql && +.Dq Li && and -.Ql \*(Ba\*(Ba +.Dq Li \*(Ba\*(Ba operators, while it need not follow -.Ql & , -.Ql \*(Ba& , +.Dq Li & , +.Dq Li \*(Ba& , or -.Ql \&; . +.Dq Li \&; . The exit status of a list is that of the last command executed, with the exception of asynchronous lists, for which the exit status is 0. .Pp @@ -673,9 +673,9 @@ Compound construct; .Ar list is executed, but not in a subshell. Note that -.Ql { +.Dq Li { and -.Ql } +.Dq Li } are reserved words, not meta-characters. .It Xo case Ar word No in .Oo Op \&( @@ -720,11 +720,11 @@ The list .Ic terminator Ns s are: .Bl -tag -width 4n -.It Ql ;; +.It Dq Li ;; Terminate after the list. -.It Ql ;&\& +.It Dq Li \&;& Fall through into the next list. -.It Ql ;\*(Ba\& +.It Dq Li \&;\*(Ba Evaluate the remaining pattern-list tuples. .El .Pp @@ -748,9 +748,8 @@ is set to the word and is executed. If .Ic in -is not used to specify a word list, the positional parameters -($1, $2, etc.)\& -are used instead. +is not used to specify a word list, the positional parameters ($1, $2, +etc.) are used instead. For historical reasons, open and close braces may be used instead of .Ic do and @@ -809,8 +808,9 @@ An enumerated list of the specified .Ar word Ns (s) is printed on standard error, followed by a prompt .Po -.Ev PS3: normally -.Sq #?\ \& +.Ev PS3 : +normally +.Dq Li #?\ \& .Pc . A number corresponding to one of the enumerated words is then read from standard input, @@ -835,7 +835,7 @@ is read, an interrupt is received, or a .Ic break statement is executed inside the loop. If -.Dq in word ... +.Dq in Ar word ... is omitted, the positional parameters are used (i.e. $1, $2, etc.). For historical reasons, open and close braces may be used instead of @@ -914,7 +914,7 @@ reserved word. The arithmetic expression .Ar expression is evaluated; equivalent to -.Dq let expression +.Dq Li let \&" Ns Ar expression Ns \&" (see .Sx Arithmetic expressions and the @@ -937,22 +937,22 @@ and .Fl o .Pq OR operators are replaced with -.Ql && +.Dq Li && and -.Ql \*(Ba\*(Ba , +.Dq Li \*(Ba\*(Ba , respectively. .It Operators (e.g.\& -.Sq Fl f , -.Sq = , -.Sq \&! ) +.Dq Li \-f , +.Dq Li = , +.Dq Li \&! ) must be unquoted. .It Parameter, command, and arithmetic substitutions are performed as expressions are evaluated and lazy expression evaluation is used for the -.Ql && +.Dq Li && and -.Ql \*(Ba\*(Ba +.Dq Li \*(Ba\*(Ba operators. This means that in the following statement, .Ic $(\*(Ltfoo) @@ -964,9 +964,9 @@ $ [[ \-r foo && $(\*(Ltfoo) = b*r ]] .Ed .It The second operand of the -.Sq != +.Dq Li != and -.Sq = +.Dq Li = expressions are a subset of patterns (e.g. the comparison .Ic \&[[ foobar = f*r ]] succeeds). @@ -993,10 +993,10 @@ case both the .Ql \e and the newline are stripped. Second, a single quote -.Pq Dq \*(aq +.Pq Dq Li \*(aq quotes everything up to the next single quote (this may span lines). Third, a double quote -.Pq Sq \&" +.Pq Ql \&" quotes all characters, except .Ql $ , .Ql \e , @@ -1045,68 +1045,68 @@ or GNU .Nm bash style escapes are translated. These include -.Ql \ea , -.Ql \eb , -.Ql \ef , -.Ql \en , -.Ql \er , -.Ql \et , -.Ql \eU######## , -.Ql \eu#### , +.Dq Li \ea , +.Dq Li \eb , +.Dq Li \ef , +.Dq Li \en , +.Dq Li \er , +.Dq Li \et , +.Dq Li \eU######## , +.Dq Li \eu#### , and -.Ql \ev . +.Dq Li \ev . For -.Ql \eU######## +.Dq Li \eU######## and -.Ql \eu#### , +.Dq Li \eu#### , .Dq # means a hexadecimal digit, of thich there may be none up to four or eight; these escapes translate a Unicode codepoint to UTF-8. Furthermore, -.Ql \eE +.Dq Li \eE and -.Ql \ee +.Dq Li \ee expand to the escape character. .Pp In the .Ic print builtin mode, -.Ql \e" , -.Ql \e\*(aq , +.Dq Li \e" , +.Dq Li \e\*(aq , and -.Ql \e? +.Dq Li \e? are explicitly excluded; octal sequences must have the none up to three octal digits .Dq # prefixed with the digit zero -.Pq Ql \e0### ; +.Pq Dq Li \e0### ; hexadecimal sequences -.Ql \ex## +.Dq Li \ex## are limited to none up to two hexadecimal digits .Dq # ; both octal and hexadecimal sequences convert to raw octets; -.Ql \e# , +.Dq Li \e# , where # is none of the above, translates to \e# (backslashes are retained). .Pp Backslash expansion in the C style mode slightly differs: octal sequences -.Ql \e### +.Dq Li \e### must have no digit zero prefixing the one up to three octal digits .Dq # and yield raw octets; hexadecimal sequences -.Ql \ex#* +.Dq Li \ex#* greedily eat up as many hexadecimal digits .Dq # as they can and terminate with the first non-hexadecimal digit; these translate a Unicode codepoint to UTF-8. The sequence -.Ql \ec# , +.Dq Li \ec# , where .Dq # is any octet, translates to Ctrl-# (which basically means, -.Ql \ec? +.Dq Li \ec? becomes DEL, everything else is bitwise ANDed with 0x1F). Finally, -.Ql \e# , +.Dq Li \e# , where # is none of the above, translates to # (has the backslash trimmed), even if it is a newline. .Ss Aliases @@ -1251,16 +1251,16 @@ whitespace does create an empty field. Example: If .Ev IFS is set to -.Dq \*(Ltspace\*(Gt: , +.Dq Li \*(Ltspace\*(Gt: , and VAR is set to -.Dq \*(Ltspace\*(GtA\*(Ltspace\*(Gt:\*(Ltspace\*(Gt\*(Ltspace\*(GtB::D , +.Dq Li \*(Ltspace\*(GtA\*(Ltspace\*(Gt:\*(Ltspace\*(Gt\*(Ltspace\*(GtB::D , the substitution for $VAR results in four fields: -.Sq A , -.Sq B , -.Sq +.Dq Li A , +.Dq Li B , +.Dq (an empty field), and -.Sq D . +.Dq Li D . Note that if the .Ev IFS parameter is set to the empty string, no field splitting is done; @@ -1270,18 +1270,18 @@ Also, note that the field splitting applies only to the immediate result of the substitution. Using the previous example, the substitution for $VAR:E results in the fields: -.Sq A , -.Sq B , -.Sq , +.Dq Li A , +.Dq Li B , +.Dq , and -.Sq D:E , +.Dq Li D:E , not -.Sq A , -.Sq B , -.Sq , -.Sq D , +.Dq Li A , +.Dq Li B , +.Dq , +.Dq Li D , and -.Sq E . +.Dq Li E . This behavior is POSIX compliant, but incompatible with some other shell implementations which do field splitting on the word which contained the substitution or use @@ -1326,18 +1326,18 @@ has the same effect as .Pp Note that some shells do not use a recursive parser for command substitutions, leading to failure for certain constructs; to be portable, use as workaround -.Ql x=$(cat) \*(Lt\*(Lt"EOF" +.Dq Li x=$(cat) \*(Lt\*(Lt\eEOF (or the newline-keeping -.Ql x=\*(Lt\*(Lt"EOF" +.Dq Li x=\*(Lt\*(Lt\eEOF extension) instead to merely slurp the string. .St -p1003.1 -recommends to use case statements of the form -.Ql "x=$(case $foo in (bar) echo $bar ;; (*) echo $baz ;; esac)" +recommends using case statements of the form +.Li "x=$(case $foo in (bar) echo $bar ;; (*) echo $baz ;; esac)" instead, which would work but not serve as example for this portability issue. .Bd -literal -offset indent x=$(case $foo in bar) echo $bar ;; *) echo $baz ;; esac) # above fails to parse on old shells; below is the workaround -x=$(eval $(cat)) \*(Lt\*(Lt"EOF" +x=$(eval $(cat)) \*(Lt\*(Lt\eEOF case $foo in bar) echo $bar ;; *) echo $baz ;; esac EOF .Ed @@ -1395,18 +1395,18 @@ is set, in which case an error occurs. .Pp Parameters can be assigned values in a number of ways. First, the shell implicitly sets some parameters like -.Ql # , -.Ql PWD , +.Dq Li # , +.Dq Li PWD , and -.Ql $ ; +.Dq Li $ ; this is the only way the special single character parameters are set. Second, parameters are imported from the shell's environment at startup. Third, parameters can be assigned values on the command line: for example, .Ic FOO=bar sets the parameter -.Dq FOO +.Dq Li FOO to -.Dq bar ; +.Dq Li bar ; multiple parameter assignments can be given on a single command line and they can be followed by a simple-command, in which case the assignments are in effect only for the duration of the command (such assignments are also @@ -1505,12 +1505,12 @@ is printed on standard error (preceded by .Ar name : ) and an error occurs (normally causing termination of a shell script, function, or script sourced using the -.Sq \&. +.Dq Li \&. built-in). If .Ar word is omitted, the string -.Dq parameter null or not set +.Dq Li parameter null or not set is used instead. .El .Pp @@ -1520,7 +1520,7 @@ is actually considered quoted, and special parsing rules apply. The parsing rules also differ on whether the expression is double-quoted: .Ar word then uses double-quoting rules, except for the double quote itself -.Pq Sq \&" +.Pq Ql \&" and the closing brace, which, if backslash escaped, gets quote removal applied. .Pp In the above modifiers, the @@ -1546,8 +1546,8 @@ will be substituted in scalar context): The number of positional parameters if .Ar name is -.Ql * , -.Ql @ , +.Dq Li * , +.Dq Li @ , or not specified; otherwise the length .Pq in characters of the string value of parameter @@ -1618,7 +1618,7 @@ Cannot be applied to a vector .Pf %% Ar pattern No } .Xc .Sm on -Like ${..#..} substitution, but it deletes from the end of the value. +Like ${...#...} substitution, but it deletes from the end of the value. Cannot be applied to a vector. .Pp .Sm off @@ -1765,7 +1765,7 @@ command below for a list of options). .It Ev \&? The exit status of the last non-asynchronous command executed. If the last command was killed by a signal, -.Ic $?\& +.Ic \&$? is set to 128 plus the signal number, but at most 255. .It Ev 0 The name of the shell, determined as follows: @@ -1786,7 +1786,7 @@ keyword (i.e. a Korn shell style function). .It Ev 1 No .. Ev 9 The first nine positional parameters that were supplied to the shell, function, or script sourced using the -.Sq \&. +.Dq Li \&. built-in. Further positional parameters may be accessed using .Pf ${ Ar number Ns } . @@ -1831,7 +1831,7 @@ built-in command. Note that if .Ev CDPATH is set and does not contain -.Sq \&. +.Dq Li \&. or an empty string element, the current directory is not searched. Also, the .Ic cd @@ -1862,7 +1862,7 @@ Time since the epoch, as returned by formatted as decimal .Va tv_sec followed by a dot -.Pq Sq \&. +.Pq Ql \&. and .Va tv_usec padded to exactly six decimal digits. @@ -1871,7 +1871,7 @@ If set, this parameter is assumed to contain the shell that is to be used to execute commands that .Xr execve 2 fails to execute and which do not start with a -.Dq #! Ns Ar shell +.Dq Li #! Ns Ar shell sequence. .It Ev FCEDIT The editor used by the @@ -2033,11 +2033,11 @@ to process arguments from the beginning the next time it is invoked. .It Ev PATH A colon (semicolon on OS/2) separated list of directories that are searched when looking for commands and files sourced using the -.Sq \&. +.Dq Li \&. command (see below). An empty string resulting from a leading or trailing colon, or two adjacent colons, is treated as a -.Sq \&. +.Dq Li \&. (the current directory). .It Ev PGRP The process ID of the shell's process group leader. @@ -2057,21 +2057,21 @@ command below). A literal .Ql \&! can be put in the prompt by placing -.Ql !! +.Dq Li !! in .Ev PS1 . .Pp The default prompt is -.Sq $\ \& +.Dq Li $\ \& for non-root users, -.Sq #\ \& +.Dq Li #\ \& for root. If .Nm is invoked by root and .Ev PS1 does not contain a -.Sq # +.Ql # character, the default value will be used even if .Ev PS1 already exists in the environment. @@ -2132,14 +2132,14 @@ PS1=$'\e1\er\e1\ee[7m\e1$PWD\e1\ee[0m\e1\*(Gt ' .Ed .It Ev PS2 Secondary prompt string, by default -.Sq \*(Gt\ \& , +.Dq Li \*(Gt\ \& , used when more input is needed to complete a command. .It Ev PS3 Prompt used by the .Ic select statement when reading a menu selection. The default is -.Sq #?\ \& . +.Dq Li #?\ \& . .It Ev PS4 Used to prefix commands that are printed during execution tracing (see the .Ic set Fl x @@ -2147,9 +2147,9 @@ command below). Parameter, command, and arithmetic substitutions are performed before it is printed. The default is -.Sq +\ \& . +.Dq Li +\ \& . You may want to set it to -.Sq \&[$EPOCHREALTIME]\ \& +.Dq Li \&[$EPOCHREALTIME]\ \& instead, to include timestamps. .It Ev PWD The current working directory. @@ -2221,7 +2221,7 @@ and tilde expansion is done after any assignment (i.e. after the equals sign) or after an unquoted colon -.Pq Sq \&: ; +.Pq Ql \&: ; login names are also delimited by colons. .Pp The home directory of previously expanded login names are cached and re-used. @@ -2248,17 +2248,17 @@ words, each of which is the concatenation of and .Ar suffix (e.g.\& -.Dq a{c,b{X,Y},d}e +.Dq Li a{c,b{X,Y},d}e expands to four words: -.Dq ace , -.Dq abXe , -.Dq abYe , +.Dq Li ace , +.Dq Li abXe , +.Dq Li abYe , and -.Dq ade ) . +.Dq Li ade ) . As noted in the example, brace expressions can be nested and the resulting words are not sorted. Brace expressions must contain an unquoted comma -.Pq Sq \&, +.Pq Ql \&, for expansion to occur (e.g.\& .Ic {} and @@ -2275,7 +2275,7 @@ A file name pattern is a word containing one or more unquoted or .Ql \&! characters or -.Dq \&[..] +.Dq Li \&[...] sequences. Once brace expansion has been performed, the shell replaces file name patterns with the sorted names of all the files that match the pattern @@ -2286,14 +2286,14 @@ The pattern elements have the following meaning: Matches any single character. .It \&* Matches any sequence of octets. -.It \&[..] +.It \&[...] Matches any of the octets inside the brackets. Ranges of octets can be specified by separating two octets by a .Ql \- (e.g.\& -.Dq \&[a0\-9] +.Dq Li \&[a0\-9] matches the letter -.Sq a +.Ql a or any digit). In order to represent itself, a .Ql \- @@ -2306,8 +2306,8 @@ Also, a .Ql \&! appearing at the start of the list has special meaning (see below), so to represent itself it must be quoted or appear later in the list. -.It \&[!..] -Like [..], +.It \&[!...] +Like [...], except it matches any octet not inside the brackets. .Sm off .It *( Ar pattern\*(Ba No ...\*(Ba Ar pattern ) @@ -2318,9 +2318,9 @@ Example: The pattern .Ic *(foo\*(Babar) matches the strings .Dq , -.Dq foo , -.Dq bar , -.Dq foobarfoo , +.Dq Li foo , +.Dq Li bar , +.Dq Li foobarfoo , etc. .Sm off .It +( Ar pattern\*(Ba No ...\*(Ba Ar pattern ) @@ -2330,9 +2330,9 @@ specified patterns. Example: The pattern .Ic +(foo\*(Babar) matches the strings -.Dq foo , -.Dq bar , -.Dq foobar , +.Dq Li foo , +.Dq Li bar , +.Dq Li foobar , etc. .Sm off .It ?( Ar pattern\*(Ba No ...\*(Ba Ar pattern ) @@ -2343,9 +2343,9 @@ Example: The pattern .Ic ?(foo\*(Babar) only matches the strings .Dq , -.Dq foo , +.Dq Li foo , and -.Dq bar . +.Dq Li bar . .Sm off .It @( Ar pattern\*(Ba No ...\*(Ba Ar pattern ) .Sm on @@ -2353,9 +2353,9 @@ Matches a string that matches one of the specified patterns. Example: The pattern .Ic @(foo\*(Babar) only matches the strings -.Dq foo +.Dq Li foo and -.Dq bar . +.Dq Li bar . .Sm off .It !( Ar pattern\*(Ba No ...\*(Ba Ar pattern ) .Sm on @@ -2363,13 +2363,13 @@ Matches any string that does not match one of the specified patterns. Examples: The pattern .Ic !(foo\*(Babar) matches all strings except -.Dq foo +.Dq Li foo and -.Dq bar ; +.Dq Li bar ; the pattern -.Ic !(*) +.Ic \&!(*) matches no strings; the pattern -.Ic !(?)*\& +.Ic \&!(?)* matches all strings (think about it). .El .Pp @@ -2380,9 +2380,9 @@ Note that .Nm mksh .Po and Nm pdksh Pc never matches -.Sq \&. +.Dq Li \&. and -.Sq .. , +.Dq Li .. , but .At .Nm ksh , @@ -2393,15 +2393,15 @@ and GNU do. .Pp Note that none of the above pattern elements match either a period -.Pq Sq \&. +.Pq Ql \&. at the start of a file name or a slash -.Pq Sq / , -even if they are explicitly used in a [..] sequence; also, the names -.Sq \&. +.Pq Ql / , +even if they are explicitly used in a [...] sequence; also, the names +.Dq Li \&. and -.Sq .. +.Dq Li .. are never matched, even by the pattern -.Sq .* . +.Dq Li .* . .Pp If the .Ic markdirs @@ -2473,13 +2473,13 @@ contains no quoted characters, the contents of the temporary file are processed as if enclosed in double quotes each time the command is executed, so parameter, command, and arithmetic substitutions are performed, along with backslash -.Pq Sq \e +.Pq Ql \e escapes for .Ql $ , .Ql \` , .Ql \e , and -.Ql \enewline , +.Dq Li \enewline , but not for .Ql \&" . If multiple here documents are used on the same command line, they are saved in @@ -2493,9 +2493,9 @@ and substitution will be performed. If .Ar marker is only a set of either single -.Dq \*(aq\*(aq +.Dq Li \*(aq\*(aq or double -.Sq \&"" +.Ql \&"" quotes with nothing in between, the here document ends at the next empty line and substitution will not be performed. .It \*(Lt\*(Lt\- Ns Ar marker @@ -2593,7 +2593,7 @@ File descriptors created by I/O redirections are private to the shell. .Ss Arithmetic expressions Integer arithmetic expressions can be used with the .Ic let -command, inside $((..)) expressions, inside array references (e.g.\& +command, inside $((...)) expressions, inside array references (e.g.\& .Ar name Ns Bq Ar expr ) , as numeric arguments to the .Ic test @@ -2608,7 +2608,7 @@ use unchecked user input, e.g. from the environment, in arithmetics! Expressions are calculated using signed arithmetic and the .Vt mksh_ari_t type (a 32-bit signed integer), unless they begin with a sole -.Sq # +.Ql # character, in which case they use .Vt mksh_uari_t .Po a 32-bit unsigned integer Pc . @@ -2658,13 +2658,13 @@ is a decimal integer specifying the base (up to 36), and .Ar number is a number in the specified base. Additionally, base-16 integers may be specified by prefixing them with -.Sq 0x +.Dq Li 0x .Pq case-insensitive in all forms of arithmetic expressions, except as numeric arguments to the .Ic test built-in utility. Prefixing numbers with a sole digit zero -.Pq Sq 0 +.Pq Dq Li 0 does not cause interpretation as octal (except in POSIX mode, as required by the standard), as that's unsafe to do. .Pp @@ -2678,9 +2678,9 @@ The .At .Nm ksh93 syntax of -.Dq \*(aqx\*(aq +.Dq Li \*(aqx\*(aq instead of -.Dq 1#x +.Dq Li 1#x is also supported. Note that NUL bytes (integral value of zero) cannot be used. An unset or empty parameter evaluates to 0 in integer context. @@ -2745,9 +2745,9 @@ with any operator precedence in .Aq Ar expr preserved. For example, -.Dq var1 *= 5 + 3 +.Dq Li var1 *= 5 + 3 is the same as specifying -.Dq var1 = var1 * (5 + 3) . +.Dq Li var1 = var1 * (5 + 3) . .It \*(Ba\*(Ba Logical OR; the result is 1 if either argument is non-zero, 0 if not. @@ -2811,7 +2811,7 @@ The non-result argument is not evaluated. .El .Ss Co-processes A co-process (which is a pipeline created with the -.Sq \*(Ba& +.Dq Li \*(Ba& operator) is an asynchronous process that the shell can both write to (using .Ic print Fl p ) and read from (using @@ -2871,7 +2871,7 @@ syntax (see below for the difference between the two forms). Functions are like .Li .\(hyscripts (i.e. scripts sourced using the -.Sq \&. +.Dq Li \&. built-in) in that they are executed in the current environment. However, unlike @@ -3108,7 +3108,7 @@ above). If the .Fl p option is used, each alias is prefixed with the string -.Dq alias\ \& . +.Dq Li alias\ \& . .Pp The .Fl t @@ -3227,7 +3227,7 @@ standard output. If a .Ar file is a single dash -.Pq Sq - +.Pq Dq Li \- or absent, read from standard input. For direct builtin calls, the .Tn POSIX @@ -3273,7 +3273,7 @@ is used. If .Ar dir is -.Ql \- , +.Dq Li \- , the previous working directory is used (see the .Ev OLDPWD parameter). @@ -3285,7 +3285,7 @@ option (logical path) is used or if the option isn't set (see the .Ic set command below), references to -.Sq .. +.Dq Li .. in .Ar dir are relative to the path used to get to the directory. @@ -3294,7 +3294,7 @@ If the option (physical path) is used or if the .Ic physical option is set, -.Sq .. +.Dq Li .. is relative to the filesystem directory tree. The .Ev PWD @@ -3402,7 +3402,7 @@ Prints its arguments (separated by spaces) followed by a newline, to the standard output. The newline is suppressed if any of the arguments contain the backslash sequence -.Ql \ec . +.Dq Li \ec . See the .Ic print command below for a list of other backslash sequences that are recognised. @@ -3424,7 +3424,7 @@ or .Ic sh option is set or this is a direct builtin call, only the first argument is treated as an option, and only if it is exactly -.Dq Fl n . +.Dq Li \-n . Backslash interpretation is disabled. .Pp .It Ic eval Ar command ... @@ -3468,7 +3468,7 @@ The shell exits with the specified exit status. If .Ar status is not specified, the exit status is the current value of the -.Ic $?\& +.Ic \&$? parameter. .Pp .It Xo @@ -3482,7 +3482,7 @@ If values are specified, the named parameters are also assigned. .Pp If no parameters are specified, all parameters with the export attribute set are printed one per line; either their names, or, if a -.Ql \- +.Dq Li \- with no option letter is specified, name=value pairs, or, with .Fl p , .Ic export @@ -3618,7 +3618,7 @@ Options end at the first (non-option argument) argument that does not start with a .Ql \- , or when a -.Ql \-\- +.Dq Li \-\- argument is encountered. .Pp Option parsing can be reset by setting @@ -3772,7 +3772,7 @@ By default, certain C escapes are translated. These include these mentioned in .Sx Backslash expansion above, as well as -.Ql \ec , +.Dq Li \ec , which is equivalent to using the .Fl n option. @@ -3843,7 +3843,7 @@ If the option (physical path) is used or if the .Ic physical option is set, the path determined from the filesystem (by following -.Sq .. +.Dq Li .. directories to the root directory) is printed. .Pp .It Xo @@ -4020,7 +4020,7 @@ Prints the resolved absolute pathname corresponding to If .Ar name ends with a slash -.Pq Sq / , +.Pq Ql / , it's also checked for existence and whether it is a directory; otherwise, .Ic realpath returns 0 if the pathname either exists or can be created immediately, @@ -4227,9 +4227,9 @@ is changed whenever one of the locale-related environment variables changes. .It Fl u \*(Ba Fl o Ic nounset Referencing of an unset parameter, other than -.Dq $@ +.Dq Li $@ or -.Dq $* , +.Dq Li $* , is treated as an error, unless one of the .Ql \- , .Ql + , @@ -4295,11 +4295,11 @@ and commands to use .Dq physical (i.e. the filesystem's) -.Sq .. +.Dq Li .. directories instead of .Dq logical directories (i.e. the shell handles -.Sq .. , +.Dq Li .. , which allows the user to be oblivious of symbolic links to directories). Clear by default. Note that setting this option does not affect the current value of the @@ -4373,7 +4373,7 @@ is always in viraw mode. These options can also be used upon invocation of the shell. The current set of options (with single letter names) can be found in the parameter -.Sq $\- . +.Dq Li $\- . .Ic set Fl o with no option name will list all the options and whether each is on or off; .Ic set +o @@ -4387,11 +4387,11 @@ compliant and print commands to restore the current options instead. Remaining arguments, if any, are positional parameters and are assigned, in order, to the positional parameters (i.e. $1, $2, etc.). If options end with -.Ql \-\- +.Dq Li \-\- and there are no remaining arguments, all positional parameters are cleared. If no options or arguments are given, the values of all names are printed. For unknown historical reasons, a lone -.Ql \- +.Dq Li \- option is treated specially \*(en it clears both the .Fl v and @@ -4402,10 +4402,7 @@ options. The positional parameters .Ar number Ns +1 , .Ar number Ns +2 , -etc. are renamed to -.Sq 1 , -.Sq 2 , -etc. +etc. are renamed to 1, 2, etc. .Ar number defaults to 1. .Pp @@ -4518,11 +4515,11 @@ or .Ql + .Pq no logical negation , for example -.Ql \-x +.Dq Li \-x or -.Ql +x +.Dq Li +x instead of -.Ql xtrace . +.Dq Li xtrace . .It Fl p Ar file .Ar file is a named pipe @@ -4631,7 +4628,7 @@ Note that some special rules are applied (courtesy of or inside the brackets .Ic \&[ ... \&] is less than five: if leading -.Ql \&! +.Dq Li \&! arguments can be stripped such that only one to three arguments remain, then the lowered comparison is executed; (thanks to XSI) parentheses .Ic \e( ... \e) @@ -4643,26 +4640,26 @@ prefer negation followed by parenthesis; the one-argument form always implies .Pp .Sy Note : A common mistake is to use -.Dq if \&[ $foo = bar \&] +.Dq Li if \&[ $foo = bar \&] which fails if parameter .Dq foo is empty or unset, if it has embedded spaces (i.e.\& .Ev IFS octets), or if it is a unary operator like -.Sq \&! +.Dq Li \&! or -.Sq Fl n . +.Dq Li \-n . Use tests like -.Dq if \&[ x\&"$foo\&" = x"bar" \&] +.Dq Li if \&[ x\&"$foo\&" = x"bar" \&] instead, or the double-bracket operator -.Dq if \&[[ $foo = bar \&]] +.Dq Li if \&[[ $foo = bar \&]] or, to avoid pattern matching (see .Ic \&[[ above): -.Dq if \&[[ $foo = \&"$bar" \&]] +.Dq Li if \&[[ $foo = \&"$bar" \&]] .Pp The -.Ic \&[[ ... ]] +.Ic \&[[ ... \&]] construct is not only more secure to use but also often faster. .Pp .It Xo @@ -4722,8 +4719,8 @@ The format of the output is: If the first operand is a decimal unsigned integer, this resets all specified signals to the default action, i.e. is the same as calling .Ic trap -with a minus sign -.Pq Sq \- +with a dash +.Pq Dq Li \- as .Ar handler , followed by the arguments @@ -4735,9 +4732,8 @@ Sets a trap handler that is to be executed when any of the specified .Ar signal Ns s are received. .Ar handler -is either an empty string, indicating the signals are to be ignored, -a minus sign -.Pq Sq \- , +is either an empty string, indicating the signals are to be ignored, a dash +.Pq Dq Li \- , indicating that the default action is to be taken for the signals .Pq see Xr signal 3 , or a string containing shell commands to be executed at the first opportunity @@ -4817,7 +4813,7 @@ arguments, parameter attributes are displayed; if no options are used, the current attributes of all parameters are printed as .Ic typeset commands; if an option is given (or -.Ql \- +.Dq Li \- with no option letter), all parameters and their values with the specified attributes are printed; if options are introduced with .Ql + , @@ -5134,11 +5130,11 @@ Symbolic masks are like those used by When used, they describe what permissions may be made available (as opposed to octal masks in which a set bit means the corresponding bit is to be cleared). For example, -.Dq ug=rwx,o= +.Dq Li ug=rwx,o= sets the mask so files will not be readable, writable, or executable by .Dq others , and is equivalent (on most systems) to the octal mask -.Dq 007 . +.Dq Li 007 . .Pp .It Xo .Ic unalias @@ -5256,7 +5252,7 @@ cannot be. .Pp When a job is created, it is assigned a job number. For interactive shells, this number is printed inside -.Dq \&[..] , +.Dq Li \&[...] , followed by the process IDs of the processes in the job when an asynchronous command is run. A job may be referred to in the @@ -5268,10 +5264,9 @@ and .Ic wait commands either by the process ID of the last process in the command pipeline (as stored in the -.Ic $!\& -parameter) or by prefixing the job number with a percent -sign -.Pq Sq % . +.Ic \&$! +parameter) or by prefixing the job number with a percent sign +.Pq Ql % . Other percent sequences can also be used to refer to jobs: .Bl -tag -width "%+ x %% x %XX" .It %+ \*(Ba %% \*(Ba % @@ -5334,7 +5329,7 @@ The job was killed by a signal (e.g. memory fault, hangup); use .Ic kill Fl l for a list of signal descriptions. The -.Dq core dumped +.Dq Li core dumped message indicates the process created a core file. .El .It Ar command @@ -5399,7 +5394,7 @@ Numbers with a leading digit zero are interpreted as octal. The .Nm echo builtin does not interpret backslashes and only supports the exact option -.Dq Fl n . +.Dq Li \-n . .It \&... (list is incomplete and may change for R54) .El @@ -5420,7 +5415,7 @@ child processes. The .Nm echo builtin does not interpret backslashes and only supports the exact option -.Dq Fl n . +.Dq Li \-n . .It The substitution operations .Sm off @@ -5564,9 +5559,9 @@ characters. .Xc Moves the cursor backward to the beginning of the word; words consist of alphanumerics, underscore -.Pq Sq _ , +.Pq Ql _ , and dollar sign -.Pq Sq $ +.Pq Ql $ characters. .It beginning\-of\-history: \*(ha[\*(Lt Moves to the beginning of the history. @@ -5997,7 +5992,7 @@ A .Dq word is a sequence of letters, digits, and underscore characters or a sequence of non-letter, non-digit, non-underscore, and non-whitespace characters (e.g.\& -.Dq ab2*&\*(ha +.Dq Li ab2*&\*(ha contains two words) and a .Dq big-word is a sequence of non-whitespace characters. @@ -6020,7 +6015,7 @@ insert mode; if is not specified, the last word is inserted. .It # Insert the comment character -.Pq Sq # +.Pq Ql # at the start of the current line and return the line to the shell (equivalent to .Ic I#\*(haJ ) . @@ -6059,7 +6054,7 @@ or follows one of the characters or .Ql \&) , and does not contain a slash -.Pq Sq / , +.Pq Ql / , then command expansion is done; otherwise file name expansion is done. Command expansion will match the big-word against all aliases, functions, and built-in commands as well as any executable files found by searching the @@ -6680,7 +6675,7 @@ In near future, (Unicode) locale tracking will be implemented though. .Sh BUGS Suspending (using \*(haZ) pipelines like the one below will only suspend the currently running part of the pipeline; in this example, -.Dq fubar +.Dq Li fubar is immediately printed on suspension (but not later after an .Ic fg ) . .Bd -literal -offset indent From fa94f0339e10c4c24c0a232ac640f111c51084e7 Mon Sep 17 00:00:00 2001 From: tg Date: Wed, 24 Aug 2016 20:50:11 +0000 Subject: [PATCH 04/31] =?UTF-8?q?experiment=20with=20GCC=205=E2=80=99s=20n?= =?UTF-8?q?ew=20-malign-data=3Dabi?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Build.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Build.sh b/Build.sh index d31a7ca..99141c1 100644 --- a/Build.sh +++ b/Build.sh @@ -1,5 +1,5 @@ #!/bin/sh -srcversion='$MirOS: src/bin/mksh/Build.sh,v 1.702 2016/08/10 18:20:16 tg Exp $' +srcversion='$MirOS: src/bin/mksh/Build.sh,v 1.703 2016/08/24 20:50:11 tg Exp $' #- # Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, # 2011, 2012, 2013, 2014, 2015, 2016 @@ -1458,6 +1458,7 @@ gcc) ac_flags $t_use $t_name "$t_cflags" \ "if gcc supports $t_cflags $t_ldflags" "$t_ldflags" done + ac_flags 1 data_abi_align -malign-data=abi i=1 ;; hpcc) From 61969809e4674dd5a19aa08eb668efa83b2bad72 Mon Sep 17 00:00:00 2001 From: tg Date: Thu, 25 Aug 2016 16:21:14 +0000 Subject: [PATCH 05/31] =?UTF-8?q?read(2)=20and=20write(2)=20don=E2=80=99t?= =?UTF-8?q?=20EINTR=20for=20fast=20input=20(LP#1616692)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- funcs.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/funcs.c b/funcs.c index e052fac..9ec837a 100644 --- a/funcs.c +++ b/funcs.c @@ -38,7 +38,7 @@ #endif #endif -__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.305 2016/08/01 21:38:02 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.306 2016/08/25 16:21:14 tg Exp $"); #if HAVE_KILLPG /* @@ -3776,12 +3776,15 @@ c_cat(const char **wp) /* end of file reached */ break; while (n) { + if (intrsig) + goto has_intrsig; if ((w = write(STDOUT_FILENO, cp, n)) != -1) { n -= w; cp += w; continue; } if (errno == EINTR) { + has_intrsig: restore_pipe(opipe); /* give the user a chance to ^C out */ intrcheck(); From e5e3fb3fc7da6ba4cdbabf5ed1e55f7b77885d27 Mon Sep 17 00:00:00 2001 From: tg Date: Thu, 25 Aug 2016 16:21:34 +0000 Subject: [PATCH 06/31] outstanding bumps --- Build.sh | 4 ++-- Makefile | 4 ++-- check.t | 6 +++--- lksh.1 | 8 ++++---- sh.h | 6 +++--- 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/Build.sh b/Build.sh index 99141c1..00e8aab 100644 --- a/Build.sh +++ b/Build.sh @@ -1,5 +1,5 @@ #!/bin/sh -srcversion='$MirOS: src/bin/mksh/Build.sh,v 1.703 2016/08/24 20:50:11 tg Exp $' +srcversion='$MirOS: src/bin/mksh/Build.sh,v 1.704 2016/08/25 16:21:28 tg Exp $' #- # Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, # 2011, 2012, 2013, 2014, 2015, 2016 @@ -2343,7 +2343,7 @@ addsrcs '!' HAVE_STRLCPY strlcpy.c addsrcs USE_PRINTF_BUILTIN printf.c test 1 = "$USE_PRINTF_BUILTIN" && add_cppflags -DMKSH_PRINTF_BUILTIN test 1 = "$HAVE_CAN_VERB" && CFLAGS="$CFLAGS -verbose" -add_cppflags -DMKSH_BUILD_R=530 +add_cppflags -DMKSH_BUILD_R=531 $e $bi$me: Finished configuration testing, now producing output.$ao diff --git a/Makefile b/Makefile index 0157493..b359210 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -# $MirOS: src/bin/mksh/Makefile,v 1.151 2016/08/10 18:20:17 tg Exp $ +# $MirOS: src/bin/mksh/Makefile,v 1.152 2016/08/25 16:21:30 tg Exp $ #- # Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, # 2011, 2012, 2013, 2014, 2015, 2016 @@ -57,7 +57,7 @@ CPPFLAGS+= -DMKSH_ASSUME_UTF8 -DMKSH_DISABLE_DEPRECATED \ -DHAVE_SETGROUPS=1 -DHAVE_STRERROR=0 -DHAVE_STRSIGNAL=0 \ -DHAVE_STRLCPY=1 -DHAVE_FLOCK_DECL=1 -DHAVE_REVOKE_DECL=1 \ -DHAVE_SYS_ERRLIST_DECL=1 -DHAVE_SYS_SIGLIST_DECL=1 \ - -DHAVE_PERSISTENT_HISTORY=1 -DMKSH_BUILD_R=530 + -DHAVE_PERSISTENT_HISTORY=1 -DMKSH_BUILD_R=531 CPPFLAGS+= -D${${PROG:L}_tf:C/(Mir${MAN:E}{0,1}){2}/4/:S/x/mksh_BUILD/:U} CPPFLAGS+= -I. COPTS+= -std=c89 -Wall diff --git a/check.t b/check.t index f221442..8f37753 100644 --- a/check.t +++ b/check.t @@ -1,4 +1,4 @@ -# $MirOS: src/bin/mksh/check.t,v 1.751 2016/08/12 16:48:02 tg Exp $ +# $MirOS: src/bin/mksh/check.t,v 1.752 2016/08/25 16:21:30 tg Exp $ # -*- mode: sh -*- #- # 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 expected-stdout: - @(#)MIRBSD KSH R53 2016/08/12 + @(#)MIRBSD KSH R53 2016/08/25 description: Check version of shell. stdin: @@ -39,7 +39,7 @@ name: KSH_VERSION category: shell:legacy-no --- expected-stdout: - @(#)LEGACY KSH R53 2016/08/12 + @(#)LEGACY KSH R53 2016/08/25 description: Check version of legacy shell. stdin: diff --git a/lksh.1 b/lksh.1 index 95acfca..8d297b7 100644 --- a/lksh.1 +++ b/lksh.1 @@ -1,4 +1,4 @@ -.\" $MirOS: src/bin/mksh/lksh.1,v 1.18 2016/08/10 18:20:05 tg Exp $ +.\" $MirOS: src/bin/mksh/lksh.1,v 1.19 2016/08/25 16:21:33 tg Exp $ .\"- .\" Copyright (c) 2008, 2009, 2010, 2012, 2013, 2015, 2016 .\" mirabilos @@ -74,7 +74,7 @@ .\" with -mandoc, it might implement .Mx itself, but we want to .\" use our own definition. And .Dd must come *first*, always. .\" -.Dd $Mdocdate: August 10 2016 $ +.Dd $Mdocdate: August 25 2016 $ .\" .\" Check which macro package we use, and do other -mdoc setup. .\" @@ -209,9 +209,9 @@ The string identifies .Nm as -.Dq LEGACY KSH +.Dq Li LEGACY KSH instead of -.Dq MIRBSD KSH . +.Dq Li MIRBSD KSH . Note that the rest of the version string is identical between the two shell flavours, and the behaviour and differences can change between versions; see the accompanying manual page diff --git a/sh.h b/sh.h index a6cfb6f..552192d 100644 --- a/sh.h +++ b/sh.h @@ -175,9 +175,9 @@ #endif #ifdef EXTERN -__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.786 2016/08/12 16:48:05 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.787 2016/08/25 16:21:34 tg Exp $"); #endif -#define MKSH_VERSION "R53 2016/08/12" +#define MKSH_VERSION "R53 2016/08/25" /* arithmetic types: C implementation */ #if !HAVE_CAN_INTTYPES @@ -578,7 +578,7 @@ char *ucstrstr(char *, const char *); #define mkssert(e) do { } while (/* CONSTCOND */ 0) #endif -#if (!defined(MKSH_BUILDMAKEFILE4BSD) && !defined(MKSH_BUILDSH)) || (MKSH_BUILD_R != 530) +#if (!defined(MKSH_BUILDMAKEFILE4BSD) && !defined(MKSH_BUILDSH)) || (MKSH_BUILD_R != 531) #error Must run Build.sh to compile this. extern void thiswillneverbedefinedIhope(void); int From a838564cec27803de04ffc06b60a52b80dbb85e5 Mon Sep 17 00:00:00 2001 From: tg Date: Thu, 1 Sep 2016 12:55:21 +0000 Subject: [PATCH 07/31] Unicode 9.0.0 (code and data part; FixedMisc font tbd) --- expr.c | 52 +++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 43 insertions(+), 9 deletions(-) diff --git a/expr.c b/expr.c index e40108f..4b830ab 100644 --- a/expr.c +++ b/expr.c @@ -23,7 +23,7 @@ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/expr.c,v 1.88 2016/07/27 00:55:27 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/expr.c,v 1.89 2016/09/01 12:55:21 tg Exp $"); #define EXPRTOK_DEFNS #include "exprtok.h" @@ -857,7 +857,7 @@ ksh_access(const char *fn, int mode) } #ifndef MIRBSD_BOOTFLOPPY -/* From: X11/xc/programs/xterm/wcwidth.c,v 1.8 2014/06/24 19:53:53 tg Exp $ */ +/* From: X11/xc/programs/xterm/wcwidth.c,v 1.9 */ struct mb_ucsrange { unsigned short beg; @@ -868,8 +868,8 @@ static int mb_ucsbsearch(const struct mb_ucsrange arr[], size_t elems, unsigned int val) MKSH_A_PURE; /* - * Generated by MirOS: contrib/code/Snippets/eawparse,v 1.2 2013/11/30 13:45:17 tg Exp $ - * from the Unicode Character Database, Version 7.0.0 + * Generated from the Unicode Character Database, Version 9.0.0, by + * MirOS: contrib/code/Snippets/eawparse,v 1.3 2014/11/16 12:16:24 tg Exp $ */ static const struct mb_ucsrange mb_ucs_combining[] = { @@ -899,7 +899,7 @@ static const struct mb_ucsrange mb_ucs_combining[] = { { 0x0825, 0x0827 }, { 0x0829, 0x082D }, { 0x0859, 0x085B }, - { 0x08E4, 0x0902 }, + { 0x08D4, 0x0902 }, { 0x093A, 0x093A }, { 0x093C, 0x093C }, { 0x0941, 0x0948 }, @@ -994,6 +994,7 @@ static const struct mb_ucsrange mb_ucs_combining[] = { { 0x17C9, 0x17D3 }, { 0x17DD, 0x17DD }, { 0x180B, 0x180E }, + { 0x1885, 0x1886 }, { 0x18A9, 0x18A9 }, { 0x1920, 0x1922 }, { 0x1927, 0x1928 }, @@ -1032,7 +1033,7 @@ static const struct mb_ucsrange mb_ucs_combining[] = { { 0x1CF4, 0x1CF4 }, { 0x1CF8, 0x1CF9 }, { 0x1DC0, 0x1DF5 }, - { 0x1DFC, 0x1DFF }, + { 0x1DFB, 0x1DFF }, { 0x200B, 0x200F }, { 0x202A, 0x202E }, { 0x2060, 0x2064 }, @@ -1045,13 +1046,13 @@ static const struct mb_ucsrange mb_ucs_combining[] = { { 0x3099, 0x309A }, { 0xA66F, 0xA672 }, { 0xA674, 0xA67D }, - { 0xA69F, 0xA69F }, + { 0xA69E, 0xA69F }, { 0xA6F0, 0xA6F1 }, { 0xA802, 0xA802 }, { 0xA806, 0xA806 }, { 0xA80B, 0xA80B }, { 0xA825, 0xA826 }, - { 0xA8C4, 0xA8C4 }, + { 0xA8C4, 0xA8C5 }, { 0xA8E0, 0xA8F1 }, { 0xA926, 0xA92D }, { 0xA947, 0xA951 }, @@ -1078,14 +1079,47 @@ static const struct mb_ucsrange mb_ucs_combining[] = { { 0xABED, 0xABED }, { 0xFB1E, 0xFB1E }, { 0xFE00, 0xFE0F }, - { 0xFE20, 0xFE2D }, + { 0xFE20, 0xFE2F }, { 0xFEFF, 0xFEFF }, { 0xFFF9, 0xFFFB } }; static const struct mb_ucsrange mb_ucs_fullwidth[] = { { 0x1100, 0x115F }, + { 0x231A, 0x231B }, { 0x2329, 0x232A }, + { 0x23E9, 0x23EC }, + { 0x23F0, 0x23F0 }, + { 0x23F3, 0x23F3 }, + { 0x25FD, 0x25FE }, + { 0x2614, 0x2615 }, + { 0x2648, 0x2653 }, + { 0x267F, 0x267F }, + { 0x2693, 0x2693 }, + { 0x26A1, 0x26A1 }, + { 0x26AA, 0x26AB }, + { 0x26BD, 0x26BE }, + { 0x26C4, 0x26C5 }, + { 0x26CE, 0x26CE }, + { 0x26D4, 0x26D4 }, + { 0x26EA, 0x26EA }, + { 0x26F2, 0x26F3 }, + { 0x26F5, 0x26F5 }, + { 0x26FA, 0x26FA }, + { 0x26FD, 0x26FD }, + { 0x2705, 0x2705 }, + { 0x270A, 0x270B }, + { 0x2728, 0x2728 }, + { 0x274C, 0x274C }, + { 0x274E, 0x274E }, + { 0x2753, 0x2755 }, + { 0x2757, 0x2757 }, + { 0x2795, 0x2797 }, + { 0x27B0, 0x27B0 }, + { 0x27BF, 0x27BF }, + { 0x2B1B, 0x2B1C }, + { 0x2B50, 0x2B50 }, + { 0x2B55, 0x2B55 }, { 0x2E80, 0x303E }, { 0x3040, 0xA4CF }, { 0xA960, 0xA97F }, From d18f9133c808f4f04276adba990fb31684ea2bb5 Mon Sep 17 00:00:00 2001 From: tg Date: Thu, 1 Sep 2016 12:59:12 +0000 Subject: [PATCH 08/31] =?UTF-8?q?fix=20English=20(thanks=20to=20Andreas=20?= =?UTF-8?q?Buschka);=20TIL:=20=E2=80=A2=20to=20start=20=E2=87=92=20a=20sta?= =?UTF-8?q?rt=20=E2=80=A2=20to=20begin=20=E2=87=92=20a=20beginning?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Build.sh | 8 ++++---- check.t | 10 +++++----- edit.c | 18 +++++++++--------- emacsfn.h | 4 ++-- eval.c | 6 +++--- exec.c | 4 ++-- main.c | 6 +++--- sh.h | 10 +++++----- syn.c | 6 +++--- 9 files changed, 36 insertions(+), 36 deletions(-) diff --git a/Build.sh b/Build.sh index 00e8aab..a4cac2f 100644 --- a/Build.sh +++ b/Build.sh @@ -1,5 +1,5 @@ #!/bin/sh -srcversion='$MirOS: src/bin/mksh/Build.sh,v 1.704 2016/08/25 16:21:28 tg Exp $' +srcversion='$MirOS: src/bin/mksh/Build.sh,v 1.705 2016/09/01 12:59:04 tg Exp $' #- # Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, # 2011, 2012, 2013, 2014, 2015, 2016 @@ -120,7 +120,7 @@ do_genopt() { state=3 ;; 1:@@) - # begin of data block + # start of data block o_gen=$o_gen$nl"#endif" o_gen=$o_gen$nl"#ifndef F0" o_gen=$o_gen$nl"#define F0 FN" @@ -133,7 +133,7 @@ do_genopt() { o_hdr=$o_hdr$nl$line ;; 0:@*|1:@*) - # begin of a definition block + # start of a definition block sym=`echo "$line" | sed 's/^@//'` if test $state = 0; then o_gen=$o_gen$nl"#if defined($sym)" @@ -980,7 +980,7 @@ drop us a success or failure notice or even send in diffs. $e "$bi$me: Building the MirBSD Korn Shell$ao $ui$dstversion$ao on $TARGET_OS ${TARGET_OSREV}..." # -# Begin of mirtoconf checks +# Start of mirtoconf checks # $e $bi$me: Scanning for functions... please ignore any errors.$ao diff --git a/check.t b/check.t index 8f37753..f78c266 100644 --- a/check.t +++ b/check.t @@ -1,4 +1,4 @@ -# $MirOS: src/bin/mksh/check.t,v 1.752 2016/08/25 16:21:30 tg Exp $ +# $MirOS: src/bin/mksh/check.t,v 1.753 2016/09/01 12:59:05 tg Exp $ # -*- mode: sh -*- #- # 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 expected-stdout: - @(#)MIRBSD KSH R53 2016/08/25 + @(#)MIRBSD KSH R53 2016/09/01 description: Check version of shell. stdin: @@ -39,7 +39,7 @@ name: KSH_VERSION category: shell:legacy-no --- expected-stdout: - @(#)LEGACY KSH R53 2016/08/25 + @(#)LEGACY KSH R53 2016/09/01 description: Check version of legacy shell. stdin: @@ -11754,7 +11754,7 @@ stdin: echo "before: x<$x> y<$y> z<$z> R<$REPLY>" x=${| local y - echo "begin: x<$x> y<$y> z<$z> R<$REPLY>" + echo "start: x<$x> y<$y> z<$z> R<$REPLY>" x=5 y=6 z=7 @@ -11769,7 +11769,7 @@ stdin: echo ${|true;}$(true). expected-stdout: before: x<1> y<2> z<3> R<4> - begin: x<1> y<> z<3> R<> + start: x<1> y<> z<3> R<> end: x<5> y<6> z<7> R<8> after: x<8> y<2> z<7> R<4> typeset t=$'foo\n\n' diff --git a/edit.c b/edit.c index d13df5e..dd767ff 100644 --- a/edit.c +++ b/edit.c @@ -28,7 +28,7 @@ #ifndef MKSH_NO_CMDLINE_EDITING -__RCSID("$MirOS: src/bin/mksh/edit.c,v 1.306 2016/08/01 18:42:40 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/edit.c,v 1.307 2016/09/01 12:59:08 tg Exp $"); /* * in later versions we might use libtermcap for this, but since external @@ -1048,7 +1048,7 @@ static struct x_defbindings const x_defbindings[] = { { XFUNC_end_hist, 1, '>' }, { XFUNC_goto_hist, 1, 'g' }, { XFUNC_mv_end, 0, CTRL('E') }, - { XFUNC_mv_begin, 0, CTRL('A') }, + { XFUNC_mv_beg, 0, CTRL('A') }, { XFUNC_draw_line, 0, CTRL('L') }, { XFUNC_cls, 1, CTRL('L') }, { XFUNC_meta1, 0, CTRL('[') }, @@ -1106,8 +1106,8 @@ static struct x_defbindings const x_defbindings[] = { { XFUNC_mv_back, 2, 'D' }, #ifndef MKSH_SMALL { XFUNC_vt_hack, 2, '1' }, - { XFUNC_mv_begin | 0x80, 2, '7' }, - { XFUNC_mv_begin, 2, 'H' }, + { XFUNC_mv_beg | 0x80, 2, '7' }, + { XFUNC_mv_beg, 2, 'H' }, { XFUNC_mv_end | 0x80, 2, '4' }, { XFUNC_mv_end | 0x80, 2, '8' }, { XFUNC_mv_end, 2, 'F' }, @@ -1119,7 +1119,7 @@ static struct x_defbindings const x_defbindings[] = { /* PC scancodes */ #if !defined(MKSH_SMALL) || defined(__OS2__) { XFUNC_meta3, 0, 0 }, - { XFUNC_mv_begin, 3, 71 }, + { XFUNC_mv_beg, 3, 71 }, { XFUNC_prev_com, 3, 72 }, #ifndef MKSH_SMALL { XFUNC_search_hist_up, 3, 73 }, @@ -2044,7 +2044,7 @@ x_mv_end(int c MKSH_A_UNUSED) } static int -x_mv_begin(int c MKSH_A_UNUSED) +x_mv_beg(int c MKSH_A_UNUSED) { x_goto(xbuf); return (KSTD); @@ -2328,7 +2328,7 @@ x_vt_hack(int c) case '~': x_arg = 1; x_arg_defaulted = true; - return (x_mv_begin(0)); + return (x_mv_beg(0)); case ';': /* "interesting" sequence detected */ break; @@ -4016,7 +4016,7 @@ vi_insert(int ch) else return (redo_insert(lastac - 1)); - /* { Begin nonstandard vi commands */ + /* { start nonstandard vi commands */ case CTRL('x'): expand_word(0); break; @@ -4035,7 +4035,7 @@ vi_insert(int ch) break; } /* FALLTHROUGH */ - /* End nonstandard vi commands } */ + /* end nonstandard vi commands } */ default: if (es->linelen >= es->cbufsize - 1) diff --git a/emacsfn.h b/emacsfn.h index 008db94..a1e8e82 100644 --- a/emacsfn.h +++ b/emacsfn.h @@ -19,7 +19,7 @@ */ #if defined(EMACSFN_DEFNS) -__RCSID("$MirOS: src/bin/mksh/emacsfn.h,v 1.9 2016/07/26 21:50:30 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/emacsfn.h,v 1.10 2016/09/01 12:59:09 tg Exp $"); #define FN(cname,sname,flags) static int x_##cname(int); #elif defined(EMACSFN_ENUMS) #define FN(cname,sname,flags) XFUNC_##cname, @@ -78,7 +78,7 @@ FN(meta2, "prefix-2", XF_PREFIX) FN(meta3, "prefix-3", XF_PREFIX) FN(meta_yank, "yank-pop", 0) FN(mv_back, "backward-char", XF_ARG) -FN(mv_begin, "beginning-of-line", 0) +FN(mv_beg, "beginning-of-line", 0) FN(mv_bword, "backward-word", XF_ARG) FN(mv_end, "end-of-line", 0) FN(mv_forw, "forward-char", XF_ARG) diff --git a/eval.c b/eval.c index ab1cc88..bc77a54 100644 --- a/eval.c +++ b/eval.c @@ -23,7 +23,7 @@ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.192 2016/08/01 21:38:01 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.193 2016/09/01 12:59:09 tg Exp $"); /* * string expansion @@ -62,7 +62,7 @@ typedef struct { #define IFS_WORD 0 /* word has chars (or quotes except "$@") */ #define IFS_WS 1 /* have seen IFS white-space */ #define IFS_NWS 2 /* have seen IFS non-white-space */ -#define IFS_IWS 3 /* begin of word, ignore IFS WS */ +#define IFS_IWS 3 /* beginning of word, ignore IFS WS */ #define IFS_QUOTE 4 /* beg.w/quote, become IFS_WORD unless "$@" */ static int varsub(Expand *, const char *, const char *, int *, int *); @@ -198,7 +198,7 @@ typedef struct SubType { struct tbl *var; /* variable for ${var..} */ struct SubType *prev; /* old type */ struct SubType *next; /* poped type (to avoid re-allocating) */ - size_t base; /* begin position of expanded word */ + size_t base; /* start position of expanded word */ short stype; /* [=+-?%#] action after expanded word */ short f; /* saved value of f (DOPAT, etc) */ uint8_t quotep; /* saved value of quote (for ${..[%#]..}) */ diff --git a/exec.c b/exec.c index 6383924..ec28d74 100644 --- a/exec.c +++ b/exec.c @@ -23,7 +23,7 @@ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.180 2016/08/24 20:40:00 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.181 2016/09/01 12:59:09 tg Exp $"); #ifndef MKSH_DEFAULT_EXECSHELL #define MKSH_DEFAULT_EXECSHELL MKSH_UNIXROOT "/bin/sh" @@ -911,7 +911,7 @@ scriptexec(struct op *tp, const char **ap) /* replace newline by NUL */ *cp = '\0'; - /* restore begin of shebang position (buf+0 or buf+3) */ + /* restore start of shebang position (buf+0 or buf+3) */ cp = buf + n; /* bail out if no shebang magic found */ if (cp[0] == '#' && cp[1] == '!') diff --git a/main.c b/main.c index 4198c87..14b1a17 100644 --- a/main.c +++ b/main.c @@ -34,7 +34,7 @@ #include #endif -__RCSID("$MirOS: src/bin/mksh/main.c,v 1.317 2016/08/04 20:51:35 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/main.c,v 1.318 2016/09/01 12:59:10 tg Exp $"); extern char **environ; @@ -222,11 +222,11 @@ main_init(int argc, const char *argv[], Source **sp, struct block **lp) /* determine the basename (without '-' or path) of the executable */ ccp = kshname; - goto begin_parse_kshname; + goto begin_parsing_kshname; while ((i = ccp[argi++])) { if (i == '/') { ccp += argi; - begin_parse_kshname: + begin_parsing_kshname: argi = 0; if (*ccp == '-') ++ccp; diff --git a/sh.h b/sh.h index 552192d..5b058f3 100644 --- a/sh.h +++ b/sh.h @@ -175,9 +175,9 @@ #endif #ifdef EXTERN -__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.787 2016/08/25 16:21:34 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.788 2016/09/01 12:59:11 tg Exp $"); #endif -#define MKSH_VERSION "R53 2016/08/25" +#define MKSH_VERSION "R53 2016/09/01" /* arithmetic types: C implementation */ #if !HAVE_CAN_INTTYPES @@ -1738,7 +1738,7 @@ struct ioword { #define X_EXTRA 20 /* this many extra bytes in X string */ typedef struct XString { - /* begin of string */ + /* beginning of string */ char *beg; /* length of allocated area, minus safety margin */ size_t len; @@ -1781,7 +1781,7 @@ typedef char *XStringP; /* close, return string */ #define Xclose(xs, xp) aresize((xs).beg, (xp) - (xs).beg, (xs).areap) -/* begin of string */ +/* beginning of string */ #define Xstring(xs, xp) ((xs).beg) #define Xnleft(xs, xp) ((xs).end - (xp)) /* may be less than 0 */ @@ -1797,7 +1797,7 @@ char *Xcheck_grow(XString *, const char *, size_t); */ typedef struct { - /* begin of allocated area */ + /* beginning of allocated area */ void **beg; /* currently used number of entries */ size_t len; diff --git a/syn.c b/syn.c index 8892c1a..87b7c75 100644 --- a/syn.c +++ b/syn.c @@ -23,7 +23,7 @@ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/syn.c,v 1.114 2016/08/04 20:32:14 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/syn.c,v 1.115 2016/09/01 12:59:12 tg Exp $"); struct nesting_state { int start_token; /* token than began nesting (eg, FOR) */ @@ -287,12 +287,12 @@ get_command(int cf) syniocf &= ~(KEYWORD|sALIAS); t = newtp(TCOM); t->lineno = source->line; - goto get_command_begin; + goto get_command_start; while (/* CONSTCOND */ 1) { bool check_assign_cmd; if (XPsize(args) == 0) { - get_command_begin: + get_command_start: check_assign_cmd = true; cf = sALIAS | CMDASN; } else if (t->u.evalflags) From 9c602791b24761d6f2f32ecfff0748d40fb6ba3e Mon Sep 17 00:00:00 2001 From: tg Date: Thu, 29 Sep 2016 09:04:56 +0000 Subject: [PATCH 09/31] today, Andreas Buschka learnt that the Oxford comma is an american thing (except for exactly the University of Oxford or to disambiguate) --- mksh.1 | 239 ++++++++++++++++++++++++++++----------------------------- 1 file changed, 119 insertions(+), 120 deletions(-) diff --git a/mksh.1 b/mksh.1 index c86ccaf..b65ada2 100644 --- a/mksh.1 +++ b/mksh.1 @@ -1,4 +1,4 @@ -.\" $MirOS: src/bin/mksh/mksh.1,v 1.416 2016/08/24 20:40:00 tg Exp $ +.\" $MirOS: src/bin/mksh/mksh.1,v 1.417 2016/09/29 09:04:56 tg Exp $ .\" $OpenBSD: ksh.1,v 1.160 2015/07/04 13:27:04 feinerer Exp $ .\"- .\" Copyright © 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, @@ -76,7 +76,7 @@ .\" with -mandoc, it might implement .Mx itself, but we want to .\" use our own definition. And .Dd must come *first*, always. .\" -.Dd $Mdocdate: August 24 2016 $ +.Dd $Mdocdate: September 29 2016 $ .\" .\" Check which macro package we use, and do other -mdoc setup. .\" @@ -223,7 +223,7 @@ to a .Xr tty 4 . An interactive shell has job control enabled, ignores the .Dv SIGINT , -.Dv SIGQUIT , +.Dv SIGQUIT and .Dv SIGTERM signals, and prints prompts before reading input (see the @@ -286,7 +286,7 @@ command is disabled. .It The .Ev SHELL , -.Ev ENV , +.Ev ENV and .Ev PATH parameters cannot be changed. @@ -360,7 +360,7 @@ The exit status of the shell is 127 if the command file specified on the command line could not be opened, or non-zero if a fatal syntax error occurred during the execution of a script. In the absence of fatal errors, -the exit status is that of the last command executed, or zero, if no +the exit status is that of the last command executed, or zero if no command is executed. .Ss Startup files For the actual location of these files, see @@ -383,14 +383,14 @@ The shell begins parsing its input by removing any backslash-newline combinations, then breaking it into .Em words . Words (which are sequences of characters) are delimited by unquoted whitespace -characters (space, tab, and newline) or meta-characters +characters (space, tab and newline) or meta-characters .Po .Ql \*(Lt , .Ql \*(Gt , .Ql \*(Ba , .Ql \&; , .Ql \&( , -.Ql \&) , +.Ql \&) and .Ql & .Pc . @@ -455,7 +455,7 @@ shell and must be quoted if they are to represent themselves: .Ql { , .Ql } , .Ql * , -.Ql \&? , +.Ql \&? and .Ql \&[ . The first three of these are the above mentioned quoting characters (see @@ -467,7 +467,7 @@ the .Ql # up to the nearest newline is ignored; .Ql $ -is used to introduce parameter, command, and arithmetic substitutions (see +is used to introduce parameter, command and arithmetic substitutions (see .Sx Substitution below); .Ql \` @@ -488,7 +488,7 @@ alternations (see below); and finally, .Ql * , -.Ql \&? , +.Ql \&? and .Ql \&[ are used in file name generation (see @@ -504,7 +504,7 @@ such as .Ic for and .Ic if -statements, grouping constructs, and function definitions. +statements, grouping constructs and function definitions. .Pp A simple-command consists of some combination of parameter assignments (see @@ -512,12 +512,12 @@ A simple-command consists of some combination of parameter assignments below), input/output redirections (see .Sx Input/output redirections -below), +below) and command words; the only restriction is that parameter assignments come before any command words. The command words, if any, define the command that is to be executed and its arguments. -The command may be a shell built-in command, a function, +The command may be a shell built-in command, a function or an external command (i.e. a separate executable file that is located using the .Ev PATH @@ -564,7 +564,7 @@ tokens: .Dq Li && , .Dq Li \*(Ba\*(Ba , .Dq Li & , -.Dq Li \*(Ba& , +.Dq Li \*(Ba& and .Dq Li \&; . The first two are for conditional execution: @@ -585,7 +585,7 @@ and .Dq Li \*(Ba\*(Ba have equal precedence which is higher than that of .Dq Li & , -.Dq Li \*(Ba& , +.Dq Li \*(Ba& and .Dq Li \&; , which also have equal precedence. @@ -629,7 +629,7 @@ and .Dq Li \*(Ba\*(Ba operators, while it need not follow .Dq Li & , -.Dq Li \*(Ba& , +.Dq Li \*(Ba& or .Dq Li \&; . The exit status of a list is that of the last command executed, with the @@ -649,7 +649,7 @@ elif for select while } .Pp In the following compound command descriptions, command lists (denoted as .Em list ) -that are followed by reserved words must end with a semicolon, a newline, or +that are followed by reserved words must end with a semicolon, a newline or a (syntactically correct) reserved word. For example, the following are all valid: .Bd -literal -offset indent @@ -706,7 +706,7 @@ are dropped. Note that any unquoted space before and after a pattern is stripped; any space within a pattern must be quoted. Both the word and the -patterns are subject to parameter, command, and arithmetic substitution, as +patterns are subject to parameter, command and arithmetic substitution, as well as tilde substitution. .Pp For historical reasons, open and close braces may be used instead of @@ -948,7 +948,7 @@ Operators (e.g.\& .Dq Li \&! ) must be unquoted. .It -Parameter, command, and arithmetic substitutions are performed as expressions +Parameter, command and arithmetic substitutions are performed as expressions are evaluated and lazy expression evaluation is used for the .Dq Li && and @@ -999,14 +999,14 @@ Third, a double quote .Pq Ql \&" quotes all characters, except .Ql $ , -.Ql \e , +.Ql \e and .Ql \` , up to the next unescaped double quote. .Ql $ and .Ql \` -inside double quotes have their usual meaning (i.e. parameter, arithmetic, +inside double quotes have their usual meaning (i.e. parameter, arithmetic or command substitution) except no field splitting is carried out on the results of double-quoted substitutions, and the old-style form of command substitution has backslash-quoting for double quotes enabled. @@ -1015,7 +1015,7 @@ If a inside a double-quoted string is followed by .Ql \&" , .Ql $ , -.Ql \e , +.Ql \e or .Ql \` , only the @@ -1052,7 +1052,7 @@ These include .Dq Li \er , .Dq Li \et , .Dq Li \eU######## , -.Dq Li \eu#### , +.Dq Li \eu#### and .Dq Li \ev . For @@ -1072,7 +1072,7 @@ In the .Ic print builtin mode, .Dq Li \e" , -.Dq Li \e\*(aq , +.Dq Li \e\*(aq and .Dq Li \e? are explicitly excluded; @@ -1180,14 +1180,14 @@ automatically tracked: .Xr rm 1 , .Xr sed 1 , .Xr sh 1 , -.Xr vi 1 , +.Xr vi 1 and .Xr who 1 . .Ss Substitution The first step the shell takes in executing a simple-command is to perform substitutions on the words of the command. There are three kinds of -substitution: parameter, command, and arithmetic. +substitution: parameter, command and arithmetic. Parameter substitutions, which are described in detail in the next section, take the form .Pf $ Ns Ar name @@ -1231,7 +1231,7 @@ parameter. The .Ev IFS parameter specifies a list of octets which are used to break a string up -into several words; any octets from the set space, tab, and newline that +into several words; any octets from the set space, tab and newline that appear in the .Ev IFS octets are called @@ -1251,20 +1251,19 @@ whitespace does create an empty field. Example: If .Ev IFS is set to -.Dq Li \*(Ltspace\*(Gt: , +.Dq Li \*(Ltspace\*(Gt: and VAR is set to .Dq Li \*(Ltspace\*(GtA\*(Ltspace\*(Gt:\*(Ltspace\*(Gt\*(Ltspace\*(GtB::D , the substitution for $VAR results in four fields: .Dq Li A , .Dq Li B , .Dq -(an empty field), -and +(an empty field) and .Dq Li D . Note that if the .Ev IFS parameter is set to the empty string, no field splitting is done; -if it is unset, the default value of space, tab, and newline is used. +if it is unset, the default value of space, tab and newline is used. .Pp Also, note that the field splitting applies only to the immediate result of the substitution. @@ -1272,14 +1271,14 @@ Using the previous example, the substitution for $VAR:E results in the fields: .Dq Li A , .Dq Li B , -.Dq , +.Dq and .Dq Li D:E , not .Dq Li A , .Dq Li B , .Dq , -.Dq Li D , +.Dq Li D and .Dq Li E . This behavior is POSIX compliant, but incompatible with some other shell @@ -1307,7 +1306,7 @@ form, a .Ql \e followed by any of .Ql $ , -.Ql \` , +.Ql \` or .Ql \e is stripped (as is @@ -1372,7 +1371,7 @@ That is, they are a 32-bit unsigned integer. .Pp Parameter substitutions take the form .Pf $ Ns Ar name , -.Pf ${ Ns Ar name Ns } , +.Pf ${ Ns Ar name Ns } or .Sm off .Pf ${ Ar name Oo Ar expr Oc } @@ -1396,7 +1395,7 @@ is set, in which case an error occurs. Parameters can be assigned values in a number of ways. First, the shell implicitly sets some parameters like .Dq Li # , -.Dq Li PWD , +.Dq Li PWD and .Dq Li $ ; this is the only way the special single character parameters are set. @@ -1420,7 +1419,7 @@ is also recognised; the old and new values are immediately concatenated. The fourth way of setting a parameter is with the .Ic export , .Ic global , -.Ic readonly , +.Ic readonly and .Ic typeset commands; see their descriptions in the @@ -1432,7 +1431,7 @@ and .Ic select loops set parameters as well as the .Ic getopts , -.Ic read , +.Ic read and .Ic set Fl A commands. @@ -1504,7 +1503,7 @@ it is substituted; otherwise, is printed on standard error (preceded by .Ar name : ) and an error occurs (normally causing termination of a shell script, function, -or script sourced using the +or a script sourced using the .Dq Li \&. built-in). If @@ -1530,7 +1529,7 @@ can be omitted, in which case the conditions only depend on being set (as opposed to set and not empty). If .Ar word -is needed, parameter, command, arithmetic, and tilde substitution are performed +is needed, parameter, command, arithmetic and tilde substitution are performed on it; if .Ar word is not needed, it is not evaluated. @@ -1547,7 +1546,7 @@ The number of positional parameters if .Ar name is .Dq Li * , -.Dq Li @ , +.Dq Li @ or not specified; otherwise the length .Pq in characters of the string value of parameter @@ -1752,7 +1751,7 @@ If no background processes have been started, the parameter is not set. .It Ev \&# The number of positional parameters ($1, $2, etc.). .It Ev \&$ -The PID of the shell, or the PID of the original shell if it is a subshell. +The PID of the shell or, if it is a subshell, the PID of the original shell. Do .Em NOT use this mechanism for generating temporary file names; see @@ -1844,9 +1843,9 @@ value as reported by .Xr stty 1 is non-zero and sane enough (minimum is 12x3); similar for .Ev LINES . -This parameter is used by the interactive line editing modes, and by the +This parameter is used by the interactive line editing modes and by the .Ic select , -.Ic set Fl o , +.Ic set Fl o and .Ic kill Fl l commands to format information columns. @@ -1920,7 +1919,7 @@ below). .It Ev IFS Internal field separator, used during substitution and by the .Ic read -command, to split values into distinct arguments; normally set to space, tab, +command, to split values into distinct arguments; normally set to space, tab and newline. See .Sx Substitution @@ -2018,7 +2017,7 @@ See The previous working directory. Unset if .Ic cd -has not successfully changed directories since the shell started, or if the +has not successfully changed directories since the shell started or if the shell doesn't know where it is. .It Ev OPTARG When using @@ -2048,7 +2047,7 @@ one by one, of the last pipeline run in the foreground. The process ID of the shell's parent. .It Ev PS1 The primary prompt for interactive shells. -Parameter, command, and arithmetic +Parameter, command and arithmetic substitutions are performed, and .Ql \&! is replaced with the current command number (see the @@ -2108,7 +2107,7 @@ if you did not have any non-printing characters. Since Backslashes and other special characters may be interpreted by the shell, to set .Ev PS1 -either escape the backslash itself, +either escape the backslash itself or use double quotes. The latter is more practical. This is a more complex example, @@ -2144,7 +2143,7 @@ The default is Used to prefix commands that are printed during execution tracing (see the .Ic set Fl x command below). -Parameter, command, and arithmetic substitutions are performed +Parameter, command and arithmetic substitutions are performed before it is printed. The default is .Dq Li +\ \& . @@ -2179,7 +2178,7 @@ If the time is exceeded, the shell exits. .It Ev TMPDIR The directory temporary shell files are created in. If this parameter is not -set, or does not contain the absolute path of a writable directory, temporary +set or does not contain the absolute path of a writable directory, temporary files are created in .Pa /tmp . .It Ev USER_ID @@ -2193,12 +2192,12 @@ The characters following the tilde, up to the first .Ql / , if any, are assumed to be a login name. If the login name is empty, -.Ql + , +.Ql + or .Ql \- , the simplified value of the .Ev HOME , -.Ev PWD , +.Ev PWD or .Ev OLDPWD parameter is substituted, respectively. @@ -2215,7 +2214,7 @@ in the arguments of .Ic alias , .Ic export , .Ic global , -.Ic readonly , +.Ic readonly and .Ic typeset ) , tilde expansion is done after any assignment @@ -2227,7 +2226,7 @@ login names are also delimited by colons. The home directory of previously expanded login names are cached and re-used. The .Ic alias Fl d -command may be used to list, change, and add to this cache (e.g.\& +command may be used to list, change and add to this cache (e.g.\& .Ic alias \-d fac=/usr/local/facilities; cd \*(TIfac/bin ) . .Ss Brace expansion (alternation) Brace expressions take the following form: @@ -2244,7 +2243,7 @@ The expressions are expanded to .Ar N words, each of which is the concatenation of .Ar prefix , -.Ar str Ns i , +.Ar str Ns i and .Ar suffix (e.g.\& @@ -2252,7 +2251,7 @@ and expands to four words: .Dq Li ace , .Dq Li abXe , -.Dq Li abYe , +.Dq Li abYe and .Dq Li ade ) . As noted in the example, brace expressions can be nested and the resulting @@ -2271,7 +2270,7 @@ A file name pattern is a word containing one or more unquoted .Ql \&? , .Ql * , .Ql + , -.Ql @ , +.Ql @ or .Ql \&! characters or @@ -2343,7 +2342,7 @@ Example: The pattern .Ic ?(foo\*(Babar) only matches the strings .Dq , -.Dq Li foo , +.Dq Li foo and .Dq Li bar . .Sm off @@ -2387,7 +2386,7 @@ but .At .Nm ksh , Bourne -.Nm sh , +.Nm sh and GNU .Nm bash do. @@ -2409,8 +2408,8 @@ option is set, any directories that result from file name generation are marked with a trailing .Ql / . .Ss Input/output redirection -When a command is executed, its standard input, standard output, and standard -error (file descriptors 0, 1, and 2, respectively) are normally inherited from +When a command is executed, its standard input, standard output and standard +error (file descriptors 0, 1 and 2, respectively) are normally inherited from the shell. Three exceptions to this are commands in pipelines, for which standard input and/or standard output are those set up by the pipeline, @@ -2471,13 +2470,13 @@ If .Ar marker contains no quoted characters, the contents of the temporary file are processed as if enclosed in double quotes each time the command is executed, so -parameter, command, and arithmetic substitutions are performed, along with +parameter, command and arithmetic substitutions are performed, along with backslash .Pq Ql \e escapes for .Ql $ , .Ql \` , -.Ql \e , +.Ql \e and .Dq Li \enewline , but not for @@ -2547,7 +2546,7 @@ but a syntax error in GNU .Xc Same as .Ic \*(Gt\*(Ba Ns Ar file , -.Ic \*(Gt\*(Gt Ns Ar file , +.Ic \*(Gt\*(Gt Ns Ar file or .Ic \*(Gt& Ns Ar fd , followed by @@ -2562,11 +2561,11 @@ In any of the above redirections, the file descriptor that is redirected (i.e. standard input or standard output) can be explicitly given by preceding the redirection with a single digit. -Parameter, command, and arithmetic -substitutions, tilde substitutions, and (if the shell is interactive) +Parameter, command and arithmetic +substitutions, tilde substitutions, and, if the shell is interactive, file name generation are all performed on the .Ar file , -.Ar marker , +.Ar marker and .Ar fd arguments of redirections. @@ -2613,7 +2612,7 @@ character, in which case they use .Vt mksh_uari_t .Po a 32-bit unsigned integer Pc . .Pp -Expressions may contain alpha-numeric parameter identifiers, array references, +Expressions may contain alpha-numeric parameter identifiers, array references and integer constants and may be combined with the following C operators (listed and grouped in increasing order of precedence): .Pp @@ -2783,7 +2782,7 @@ Rotate left (right); the result is similar to shift, except that the bits shifted out at one end are shifted in at the other end, instead of zero or sign bits. .It + \- * / -Addition, subtraction, multiplication, and division. +Addition, subtraction, multiplication and division. .It % Remainder; the result is the symmetric remainder of the division of the left argument by the right. @@ -2992,9 +2991,9 @@ The EXIT trap, if set in a function, will be executed after the function returns. .El .Ss Command execution -After evaluation of command-line arguments, redirections, and parameter +After evaluation of command-line arguments, redirections and parameter assignments, the type of command is determined: a special built-in command, -a function, a normal builtin, or the name of a file to execute found using the +a function, a normal builtin or the name of a file to execute found using the .Ev PATH parameter. The checks are made in the above order. @@ -3202,7 +3201,7 @@ Exit the inner-most .Ic for , .Ic select , -.Ic until , +.Ic until or .Ic while loop. @@ -3304,7 +3303,7 @@ parameters are updated to reflect the current and old working directory, respectively. If the .Fl e -option is set for physical filesystem traversal, and +option is set for physical filesystem traversal and .Ev PWD could not be set, the exit code is 1; greater than 1 if an error occurred, 0 otherwise. @@ -3381,7 +3380,7 @@ Jumps to the beginning of the inner-most .Ic for , .Ic select , -.Ic until , +.Ic until or .Ic while loop. @@ -3517,7 +3516,7 @@ Without .Fl l , the selected commands are edited by the editor specified with the .Fl e -option, or if no +option or, if no .Fl e is specified, the editor specified by the .Ev FCEDIT @@ -3628,9 +3627,9 @@ invoked). .Pp Warning: Changing the value of the shell parameter .Ev OPTIND -to a value other than 1, or parsing different sets of arguments without +to a value other than 1 or parsing different sets of arguments without resetting -.Ev OPTIND , +.Ev OPTIND may lead to unexpected results. .Pp .It global Ar ... @@ -3682,7 +3681,7 @@ and the displayed job. .No { Ar job \*(Ba pid \*(Ba pgrp No } .Ar ... .Xc -Send the specified signal to the specified jobs, process IDs, or process +Send the specified signal to the specified jobs, process IDs or process groups. If no signal is specified, the .Dv TERM @@ -3700,8 +3699,8 @@ below for the format of .Xc Print the signal name corresponding to .Ar exit-status . -If no arguments are specified, a list of all the signals, their numbers, and -a short description of them are printed. +If no arguments are specified, a list of all the signals with their numbers +and a short description of each are printed. .Pp .It Ic let Op Ar expression ... Each expression is evaluated (see @@ -3738,7 +3737,7 @@ The file type may be .Cm b (block type device), .Cm c -(character type device), +(character type device) or .Cm p .Pq named pipe , Tn FIFO . @@ -4140,7 +4139,7 @@ This does not apply to commands whose exit status is explicitly tested by a shell construct such as .Ic if , .Ic until , -.Ic while , +.Ic while or .Ic \&! statements. @@ -4208,7 +4207,7 @@ and optionally .Fn nl_langinfo CODESET , or the .Ev LC_ALL , -.Ev LC_CTYPE , +.Ev LC_CTYPE or .Ev LANG environment variables, @@ -4232,7 +4231,7 @@ or .Dq Li $* , is treated as an error, unless one of the .Ql \- , -.Ql + , +.Ql + or .Ql = modifiers is used. @@ -4645,7 +4644,7 @@ which fails if parameter .Dq foo is empty or unset, if it has embedded spaces (i.e.\& .Ev IFS -octets), or if it is a unary operator like +octets) or if it is a unary operator like .Dq Li \&! or .Dq Li \-n . @@ -4737,7 +4736,7 @@ is either an empty string, indicating the signals are to be ignored, a dash indicating that the default action is to be taken for the signals .Pq see Xr signal 3 , or a string containing shell commands to be executed at the first opportunity -(i.e. when the current command completes, or before printing the next +(i.e. when the current command completes or before printing the next .Ev PS1 prompt) after receipt of one of the signals. .Ar signal @@ -4988,7 +4987,7 @@ If any of the .Fl l , .Fl R , .Fl U , -.Fl u , +.Fl u or .Fl Z options are changed, all others from this set are cleared, @@ -5118,7 +5117,7 @@ is concerned, a block is 512 bytes. .Op Fl S .Op Ar mask .Xc -Display or set the file permission creation mask, or umask (see +Display or set the file permission creation mask or umask (see .Xr umask 2 ) . If the .Fl S @@ -5131,7 +5130,7 @@ When used, they describe what permissions may be made available (as opposed to octal masks in which a set bit means the corresponding bit is to be cleared). For example, .Dq Li ug=rwx,o= -sets the mask so files will not be readable, writable, or executable by +sets the mask so files will not be readable, writable or executable by .Dq others , and is equivalent (on most systems) to the octal mask .Dq Li 007 . @@ -5178,7 +5177,7 @@ The exit status of is that of the last specified job; if the last job is killed by a signal, the exit status is 128 + the number of the signal (see .Ic kill Fl l Ar exit-status -above); if the last specified job can't be found (because it never existed, or +above); if the last specified job can't be found (because it never existed or had already finished), the exit status of .Ic wait is 127. @@ -5187,9 +5186,9 @@ See below for the format of .Ar job . .Ic wait -will return if a signal for which a trap has been set is received, or if a +will return if a signal for which a trap has been set is received or if a .Dv SIGHUP , -.Dv SIGINT , +.Dv SIGINT or .Dv SIGQUIT signal is received. @@ -5245,7 +5244,7 @@ commands, and the state of the terminal is saved or restored when a foreground job is stopped or restarted, respectively. .Pp Note that only commands that create processes (e.g. asynchronous commands, -subshell commands, and non-built-in, non-function commands) can be stopped; +subshell commands and non-built-in, non-function commands) can be stopped; commands like .Ic read cannot be. @@ -5259,7 +5258,7 @@ A job may be referred to in the .Ic bg , .Ic fg , .Ic jobs , -.Ic kill , +.Ic kill and .Ic wait commands either by the process ID of the last process in the command pipeline @@ -5270,7 +5269,7 @@ parameter) or by prefixing the job number with a percent sign Other percent sequences can also be used to refer to jobs: .Bl -tag -width "%+ x %% x %XX" .It %+ \*(Ba %% \*(Ba % -The most recently stopped job, or, if there are no stopped jobs, the oldest +The most recently stopped job or, if there are no stopped jobs, the oldest running job. .It %\- The job that would be the @@ -5376,7 +5375,7 @@ refer to the manual page for details. Most other historic, .At -.Nm ksh Ns -compatible , +.Nm ksh Ns -compatible or opinionated differences can be disabled by using this mode; these are: .Bl -bullet .It @@ -5452,7 +5451,7 @@ The shell supports three modes of reading command lines from a .Xr tty 4 in an interactive session, controlled by the .Ic emacs , -.Ic gmacs , +.Ic gmacs and .Ic vi options (at most one of these can be set at once). @@ -5480,7 +5479,7 @@ In these editing modes, if a line is longer than the screen width (see the parameter), a .Ql \*(Gt , -.Ql + , +.Ql + or .Ql \*(Lt character is displayed in the last column indicating that there are more @@ -5489,7 +5488,7 @@ respectively. The line is scrolled horizontally as necessary. .Pp Completed lines are pushed into the history, unless they begin with an -IFS octet or IFS white space, or are the same as the previous line. +IFS octet or IFS white space or are the same as the previous line. .Ss Emacs editing mode When the .Ic emacs @@ -5559,7 +5558,7 @@ characters. .Xc Moves the cursor backward to the beginning of the word; words consist of alphanumerics, underscore -.Pq Ql _ , +.Pq Ql _ and dollar sign .Pq Ql $ characters. @@ -5605,7 +5604,7 @@ partial word up to the cursor as its prefix, as in the .Ic complete command described above. .It complete\-list: \*(haI, \*(ha[= -Complete as much as is possible of the current word, +Complete as much as is possible of the current word and list the possible completions for it. If only one completion is possible, match as in the @@ -5780,7 +5779,7 @@ Introduces a multi-character command sequence. .Op Ar n .No \*(ha[. , \*(ha[_ .Xc -The last word, or, if given, the +The last word or, if given, the .Ar n Ns th word (zero-based) of the previous (on repeated execution, second-last, third-last, etc.) command is inserted at the cursor. @@ -5846,7 +5845,7 @@ or .It set\-mark\-command: \*(ha[ Ns Aq space Set the mark at the cursor position. .It transpose\-chars: \*(haT -If at the end of line, or if the +If at the end of line or, if the .Ic gmacs option is set, this exchanges the two previous characters; otherwise, it exchanges the previous and current characters and moves the cursor one @@ -5897,7 +5896,7 @@ editor with the following exceptions: You start out in insert mode. .It There are file name and command completion commands: -=, \e, *, \*(haX, \*(haE, \*(haF, and, optionally, +=, \e, *, \*(haX, \*(haE, \*(haF and, optionally, .Aq tab and .Aq esc . @@ -5942,7 +5941,7 @@ settings (see .Xr stty 1 ) and have their usual meaning (normal values are in parentheses): kill (\*(haU), -erase (\*(ha?), werase (\*(haW), eof (\*(haD), intr (\*(haC), and quit (\*(ha\e). +erase (\*(ha?), werase (\*(haW), eof (\*(haD), intr (\*(haC) and quit (\*(ha\e). In addition to the above, the following characters are also treated specially in insert mode: .Bl -tag -width XJXXXXM @@ -5957,7 +5956,7 @@ is undone. Erases previous character. .It \*(haJ \*(Ba \*(haM End of line. -The current line is read, parsed, and executed by the shell. +The current line is read, parsed and executed by the shell. .It \*(haV Literal next. The next character typed is not treated specially (can be used @@ -5990,8 +5989,8 @@ refers to the position between the cursor and the character preceding the cursor. A .Dq word -is a sequence of letters, digits, and underscore characters or a sequence of -non-letter, non-digit, non-underscore, and non-whitespace characters (e.g.\& +is a sequence of letters, digits and underscore characters or a sequence of +non-letter, non-digit, non-underscore and non-whitespace characters (e.g.\& .Dq Li ab2*&\*(ha contains two words) and a .Dq big-word @@ -6050,13 +6049,13 @@ or follows one of the characters .Ql \&; , .Ql \*(Ba , .Ql & , -.Ql \&( , +.Ql \&( or -.Ql \&) , +.Ql \&) and does not contain a slash .Pq Ql / , then command expansion is done; otherwise file name expansion is done. -Command expansion will match the big-word against all aliases, functions, and +Command expansion will match the big-word against all aliases, functions and built-in commands as well as any executable files found by searching the directories in the .Ev PATH @@ -6169,8 +6168,8 @@ Move forward big-words. .It % Find match. -The editor looks forward for the nearest parenthesis, bracket, or -brace and then moves the cursor to the matching parenthesis, bracket, or brace. +The editor looks forward for the nearest parenthesis, bracket or +brace and then moves the cursor to the matching parenthesis, bracket or brace. .It Xo .Oo Ar n Oc Ns f Ns Ar c .Xc @@ -6203,7 +6202,7 @@ occurrence of the character .Oo Ar n Oc Ns \&; .Xc Repeats the last -.Ic f , F , t , +.Ic f , F , t or .Ic T command. @@ -6211,7 +6210,7 @@ command. .Oo Ar n Oc Ns \&, .Xc Repeats the last -.Ic f , F , t , +.Ic f , F , t or .Ic T command, but moves in the opposite direction. @@ -6424,7 +6423,7 @@ except the buffer is pasted at the current position. Miscellaneous vi commands .Bl -tag -width Ds .It \*(haJ and \*(haM -The current line is read, parsed, and executed by the shell. +The current line is read, parsed and executed by the shell. .It \*(haL and \*(haR Redraw the current line. .It Xo @@ -6437,7 +6436,7 @@ times. Undo the last edit command. .It U Undo all changes that have been made to the current line. -.It PC Home, End, Del, and cursor keys +.It PC Home, End, Del and cursor keys They move as expected, both in insert and command mode. .It Ar intr No and Ar quit The interrupt and quit terminal characters cause the current line to be @@ -6578,7 +6577,7 @@ and parts of the BRL shell by .An Doug Kingston , .An Ron Natalie , .An Arnold Robbins , -.An Lou Salkind , +.An Lou Salkind and others. The first release of .Nm pdksh @@ -6586,12 +6585,12 @@ was created by .An Eric Gisin , and it was subsequently maintained by .An John R. MacMillan , -.An Simon J. Gerraty , +.An Simon J. Gerraty and .An Michael Rendell . The effort of several projects, such as Debian and OpenBSD, and other contributors including our users, to improve the shell is appreciated. -See the documentation, CVS, and web site for details. +See the documentation, web site and CVS for details. .Pp The BSD daemon is Copyright \(co Marshall Kirk McKusick. The complete legalese is at: From 56bdf24e548ad331214a66ba35cbf862eacc661a Mon Sep 17 00:00:00 2001 From: tg Date: Sun, 2 Oct 2016 22:21:47 +0000 Subject: [PATCH 10/31] fix error propagation in TAND/TOR constructs, noted by Martijn Dekker MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit still a bit unsure about the whole XERROK and *xerrok stuff, but… it seems to work --- check.t | 19 ++++++++++++++++--- exec.c | 4 ++-- sh.h | 4 ++-- 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/check.t b/check.t index f78c266..78c1223 100644 --- a/check.t +++ b/check.t @@ -1,4 +1,4 @@ -# $MirOS: src/bin/mksh/check.t,v 1.753 2016/09/01 12:59:05 tg Exp $ +# $MirOS: src/bin/mksh/check.t,v 1.754 2016/10/02 22:21:43 tg Exp $ # -*- mode: sh -*- #- # 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 expected-stdout: - @(#)MIRBSD KSH R53 2016/09/01 + @(#)MIRBSD KSH R53 2016/10/02 description: Check version of shell. stdin: @@ -39,7 +39,7 @@ name: KSH_VERSION category: shell:legacy-no --- expected-stdout: - @(#)LEGACY KSH R53 2016/09/01 + @(#)LEGACY KSH R53 2016/10/02 description: Check version of legacy shell. stdin: @@ -7152,6 +7152,19 @@ stdin: db_go exit 0 --- +name: exit-err-9 +description: + "set -e" versus bang pipelines +stdin: + set -e + ! false | false + echo 1 ok + ! false && false + echo 2 wrong +expected-stdout: + 1 ok +expected-exit: 1 +--- name: exit-enoent-1 description: SUSv4 says that the shell should exit with 126/127 in some situations diff --git a/exec.c b/exec.c index ec28d74..11c8a80 100644 --- a/exec.c +++ b/exec.c @@ -23,7 +23,7 @@ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.181 2016/09/01 12:59:09 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.182 2016/10/02 22:21:46 tg Exp $"); #ifndef MKSH_DEFAULT_EXECSHELL #define MKSH_DEFAULT_EXECSHELL MKSH_UNIXROOT "/bin/sh" @@ -282,7 +282,7 @@ execute(struct op * volatile t, case TOR: case TAND: - rv = execute(t->left, XERROK, xerrok); + rv = execute(t->left, XERROK, NULL); if ((rv == 0) == (t->type == TAND)) rv = execute(t->right, flags & XERROK, xerrok); else { diff --git a/sh.h b/sh.h index 5b058f3..7c7df8f 100644 --- a/sh.h +++ b/sh.h @@ -175,9 +175,9 @@ #endif #ifdef EXTERN -__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.788 2016/09/01 12:59:11 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.789 2016/10/02 22:21:47 tg Exp $"); #endif -#define MKSH_VERSION "R53 2016/09/01" +#define MKSH_VERSION "R53 2016/10/02" /* arithmetic types: C implementation */ #if !HAVE_CAN_INTTYPES From ac405dd6b7f58af6a819be546f9a2fe5f3e76950 Mon Sep 17 00:00:00 2001 From: tg Date: Sat, 22 Oct 2016 23:56:50 +0000 Subject: [PATCH 11/31] =?UTF-8?q?avoid=20even=20the=20chance=20at=20UB,=20?= =?UTF-8?q?it=E2=80=99s=20too=20risky=20with=20=E2=80=9Cpostmodern?= =?UTF-8?q?=E2=80=9D=20compilers?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main.c | 6 ++---- var.c | 6 ++---- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/main.c b/main.c index 14b1a17..8ba8038 100644 --- a/main.c +++ b/main.c @@ -34,7 +34,7 @@ #include #endif -__RCSID("$MirOS: src/bin/mksh/main.c,v 1.318 2016/09/01 12:59:10 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/main.c,v 1.319 2016/10/22 23:56:50 tg Exp $"); extern char **environ; @@ -111,10 +111,8 @@ rndsetup(void) char *cp; cp = alloc(sizeof(*bufptr) - sizeof(ALLOC_ITEM), APERM); -#ifdef DEBUG - /* clear the allocated space, for valgrind */ + /* clear the allocated space, for valgrind and to avoid UB */ memset(cp, 0, sizeof(*bufptr) - sizeof(ALLOC_ITEM)); -#endif /* undo what alloc() did to the malloc result address */ bufptr = (void *)(cp - sizeof(ALLOC_ITEM)); /* PIE or something similar provides us with deltas here */ diff --git a/var.c b/var.c index bcde2f4..0331d1e 100644 --- a/var.c +++ b/var.c @@ -28,7 +28,7 @@ #include #endif -__RCSID("$MirOS: src/bin/mksh/var.c,v 1.207 2016/08/01 21:38:07 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/var.c,v 1.208 2016/10/22 23:56:50 tg Exp $"); /*- * Variables @@ -1686,10 +1686,8 @@ rndset(unsigned long v) short r; } z; -#ifdef DEBUG - /* clear the allocated space, for valgrind */ + /* clear the allocated space, for valgrind and to avoid UB */ memset(&z, 0, sizeof(z)); -#endif h = lcg_state; BAFHFinish_reg(h); From 038cfe747614a086dfc690b32048f3fc813b4d88 Mon Sep 17 00:00:00 2001 From: tg Date: Wed, 26 Oct 2016 22:55:51 +0000 Subject: [PATCH 12/31] shave five spaces off .rodata with no functional difference --- main.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/main.c b/main.c index 8ba8038..090a85c 100644 --- a/main.c +++ b/main.c @@ -34,7 +34,7 @@ #include #endif -__RCSID("$MirOS: src/bin/mksh/main.c,v 1.319 2016/10/22 23:56:50 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/main.c,v 1.320 2016/10/26 22:55:51 tg Exp $"); extern char **environ; @@ -59,7 +59,12 @@ static void x_sigwinch(int); static const char initifs[] = "IFS= \t\n"; static const char initsubs[] = - "${PS2=> } ${PS3=#? } ${PS4=+ } ${SECONDS=0} ${TMOUT=0} ${EPOCHREALTIME=}"; + "${PS2=> }" + "${PS3=#? }" + "${PS4=+ }" + "${SECONDS=0}" + "${TMOUT=0}" + "${EPOCHREALTIME=}"; static const char *initcoms[] = { Ttypeset, "-r", initvsn, NULL, From 7fef6b129ea41208d56bb584a337d37246d363bd Mon Sep 17 00:00:00 2001 From: tg Date: Mon, 7 Nov 2016 16:55:51 +0000 Subject: [PATCH 13/31] apply patch from Brian Callahan for better pcc support --- Build.sh | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/Build.sh b/Build.sh index a4cac2f..915aa8f 100644 --- a/Build.sh +++ b/Build.sh @@ -1,5 +1,5 @@ #!/bin/sh -srcversion='$MirOS: src/bin/mksh/Build.sh,v 1.705 2016/09/01 12:59:04 tg Exp $' +srcversion='$MirOS: src/bin/mksh/Build.sh,v 1.706 2016/11/07 16:55:51 tg Exp $' #- # Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, # 2011, 2012, 2013, 2014, 2015, 2016 @@ -1487,8 +1487,12 @@ msc) ac_flags 1 wp64 "${ccpc}/Wp64" 'to enable 64-bit warnings' ;; nwcc) - i=1 #broken# ac_flags 1 ssp -stackprotect + i=1 + ;; +pcc) + ac_flags 1 fstackprotectorall -fstack-protector-all + i=1 ;; sunpro) phase=u @@ -2343,7 +2347,7 @@ addsrcs '!' HAVE_STRLCPY strlcpy.c addsrcs USE_PRINTF_BUILTIN printf.c test 1 = "$USE_PRINTF_BUILTIN" && add_cppflags -DMKSH_PRINTF_BUILTIN test 1 = "$HAVE_CAN_VERB" && CFLAGS="$CFLAGS -verbose" -add_cppflags -DMKSH_BUILD_R=531 +add_cppflags -DMKSH_BUILD_R=539 $e $bi$me: Finished configuration testing, now producing output.$ao From 5ee8ba10b3ce5b44ad753d760c3a5029411c403b Mon Sep 17 00:00:00 2001 From: tg Date: Mon, 7 Nov 2016 16:58:48 +0000 Subject: [PATCH 14/31] fix lazy evaluation with side effects; spotted by ormaaj via IRC --- Makefile | 4 ++-- check.t | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++--- expr.c | 17 +++++++++++++--- sh.h | 6 +++--- 4 files changed, 78 insertions(+), 11 deletions(-) diff --git a/Makefile b/Makefile index b359210..4165e92 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -# $MirOS: src/bin/mksh/Makefile,v 1.152 2016/08/25 16:21:30 tg Exp $ +# $MirOS: src/bin/mksh/Makefile,v 1.153 2016/11/07 16:58:45 tg Exp $ #- # Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, # 2011, 2012, 2013, 2014, 2015, 2016 @@ -57,7 +57,7 @@ CPPFLAGS+= -DMKSH_ASSUME_UTF8 -DMKSH_DISABLE_DEPRECATED \ -DHAVE_SETGROUPS=1 -DHAVE_STRERROR=0 -DHAVE_STRSIGNAL=0 \ -DHAVE_STRLCPY=1 -DHAVE_FLOCK_DECL=1 -DHAVE_REVOKE_DECL=1 \ -DHAVE_SYS_ERRLIST_DECL=1 -DHAVE_SYS_SIGLIST_DECL=1 \ - -DHAVE_PERSISTENT_HISTORY=1 -DMKSH_BUILD_R=531 + -DHAVE_PERSISTENT_HISTORY=1 -DMKSH_BUILD_R=539 CPPFLAGS+= -D${${PROG:L}_tf:C/(Mir${MAN:E}{0,1}){2}/4/:S/x/mksh_BUILD/:U} CPPFLAGS+= -I. COPTS+= -std=c89 -Wall diff --git a/check.t b/check.t index 78c1223..6f86dc5 100644 --- a/check.t +++ b/check.t @@ -1,4 +1,4 @@ -# $MirOS: src/bin/mksh/check.t,v 1.754 2016/10/02 22:21:43 tg Exp $ +# $MirOS: src/bin/mksh/check.t,v 1.755 2016/11/07 16:58:45 tg Exp $ # -*- mode: sh -*- #- # 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 expected-stdout: - @(#)MIRBSD KSH R53 2016/10/02 + @(#)MIRBSD KSH R53 2016/11/07 description: Check version of shell. stdin: @@ -39,7 +39,7 @@ name: KSH_VERSION category: shell:legacy-no --- expected-stdout: - @(#)LEGACY KSH R53 2016/10/02 + @(#)LEGACY KSH R53 2016/11/07 description: Check version of legacy shell. stdin: @@ -340,6 +340,62 @@ expected-stdout: 2 0 --- +name: arith-lazy-5-arr-n +description: Check lazy evaluation with side effects +stdin: + a=0; echo "$((0&&b[a++],a))" +expected-stdout: + 0 +--- +name: arith-lazy-5-arr-p +description: Check lazy evaluation with side effects +stdin: + a=0; echo "$((0&&(b[a++]),a))" +expected-stdout: + 0 +--- +name: arith-lazy-5-str-n +description: Check lazy evaluation with side effects +stdin: + a=0 b=a++; ((0&&b)); echo $a +expected-stdout: + 0 +--- +name: arith-lazy-5-str-p +description: Check lazy evaluation with side effects +stdin: + a=0 b=a++; ((0&&(b))); echo $a +expected-stdout: + 0 +--- +name: arith-lazy-5-tern-l-n +description: Check lazy evaluation with side effects +stdin: + a=0; echo "$((0?b[a++]:999,a))" +expected-stdout: + 0 +--- +name: arith-lazy-5-tern-l-p +description: Check lazy evaluation with side effects +stdin: + a=0; echo "$((0?(b[a++]):999,a))" +expected-stdout: + 0 +--- +name: arith-lazy-5-tern-r-n +description: Check lazy evaluation with side effects +stdin: + a=0; echo "$((1?999:b[a++],a))" +expected-stdout: + 0 +--- +name: arith-lazy-5-tern-r-p +description: Check lazy evaluation with side effects +stdin: + a=0; echo "$((1?999:(b[a++]),a))" +expected-stdout: + 0 +--- name: arith-ternary-prec-1 description: Check precedence of ternary operator vs assignment diff --git a/expr.c b/expr.c index 4b830ab..f259b0c 100644 --- a/expr.c +++ b/expr.c @@ -23,7 +23,7 @@ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/expr.c,v 1.89 2016/09/01 12:55:21 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/expr.c,v 1.90 2016/11/07 16:58:48 tg Exp $"); #define EXPRTOK_DEFNS #include "exprtok.h" @@ -326,7 +326,15 @@ evalexpr(Expr_state *es, unsigned int prec) vl = evalexpr(es, prec - 1); while ((int)(op = es->tok) >= (int)O_EQ && (int)op <= (int)O_COMMA && opprec[(int)op] == prec) { - exprtoken(es); + switch ((int)op) { + case O_TERN: + case O_LAND: + case O_LOR: + break; + default: + exprtoken(es); + } + vasn = vl; if (op != O_ASN) /* vl may not have a value yet */ @@ -340,14 +348,15 @@ evalexpr(Expr_state *es, unsigned int prec) if (!ev) es->noassign++; + exprtoken(es); vl = evalexpr(es, MAX_PREC); if (!ev) es->noassign--; if (es->tok != CTERN) evalerr(es, ET_STR, "missing :"); - exprtoken(es); if (ev) es->noassign++; + exprtoken(es); vr = evalexpr(es, P_TERN); if (ev) es->noassign--; @@ -502,6 +511,7 @@ evalexpr(Expr_state *es, unsigned int prec) case O_LAND: if (!t1) es->noassign++; + exprtoken(es); vr = intvar(es, evalexpr(es, prec - 1)); res = t1 && vr->val.u; if (!t1) @@ -510,6 +520,7 @@ evalexpr(Expr_state *es, unsigned int prec) case O_LOR: if (t1) es->noassign++; + exprtoken(es); vr = intvar(es, evalexpr(es, prec - 1)); res = t1 || vr->val.u; if (t1) diff --git a/sh.h b/sh.h index 7c7df8f..dabb074 100644 --- a/sh.h +++ b/sh.h @@ -175,9 +175,9 @@ #endif #ifdef EXTERN -__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.789 2016/10/02 22:21:47 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.790 2016/11/07 16:58:48 tg Exp $"); #endif -#define MKSH_VERSION "R53 2016/10/02" +#define MKSH_VERSION "R53 2016/11/07" /* arithmetic types: C implementation */ #if !HAVE_CAN_INTTYPES @@ -578,7 +578,7 @@ char *ucstrstr(char *, const char *); #define mkssert(e) do { } while (/* CONSTCOND */ 0) #endif -#if (!defined(MKSH_BUILDMAKEFILE4BSD) && !defined(MKSH_BUILDSH)) || (MKSH_BUILD_R != 531) +#if (!defined(MKSH_BUILDMAKEFILE4BSD) && !defined(MKSH_BUILDSH)) || (MKSH_BUILD_R != 539) #error Must run Build.sh to compile this. extern void thiswillneverbedefinedIhope(void); int From 4e855b1be28894f68c888fd579e7bc07ff118211 Mon Sep 17 00:00:00 2001 From: tg Date: Fri, 11 Nov 2016 18:44:32 +0000 Subject: [PATCH 15/31] pack local bools into a struct, for tighter stack packing --- funcs.c | 142 +++++++++++++++++++++++++++++++----------------------- histrap.c | 21 ++++---- 2 files changed, 91 insertions(+), 72 deletions(-) diff --git a/funcs.c b/funcs.c index 9ec837a..2e1cc7d 100644 --- a/funcs.c +++ b/funcs.c @@ -38,7 +38,7 @@ #endif #endif -__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.306 2016/08/25 16:21:14 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.307 2016/11/11 18:44:31 tg Exp $"); #if HAVE_KILLPG /* @@ -280,17 +280,37 @@ static void s_put(int); int c_print(const char **wp) { - int fd = 1, c; + int c; const char *s; - XString xs; char *xp; - /* print newline; expand backslash sequences */ - bool po_nl = true, po_exp = true; - /* print to history instead of file descriptor / stdout */ - bool po_hist = false; - /* print characters */ - bool po_char = false; - char ts[4]; + XString xs; + struct { + /* temporary storage for a wide character */ + mksh_ari_t wc; + /* output file descriptor (if any) */ + int fd; + /* temporary storage for a multibyte character */ + char ts[4]; + /* print trailing newline? */ + bool nl; + /* expand backslash sequences? */ + bool exp; + /* print to history instead of file descriptor / stdout? */ + bool hist; + /* print words as wide characters? */ + bool chars; + /* print a "--" argument? */ + bool pminusminus; + /* writing to a coprocess (SIGPIPE blocked)? */ + bool coproc; + bool copipe; + } po; + + po.fd = 1; + po.nl = true; + po.exp = true; + po.hist = false; + po.chars = false; if (wp[0][0] == 'e') { /* "echo" builtin */ @@ -302,7 +322,7 @@ c_print(const char **wp) * one that supports -e but does not enable it by * default */ - po_exp = false; + po.exp = false; } #endif if (Flag(FPOSIX) || @@ -313,13 +333,13 @@ c_print(const char **wp) /* Debian Policy 10.4 compliant "echo" builtin */ if (*wp && !strcmp(*wp, "-n")) { /* recognise "-n" only as the first arg */ - po_nl = false; + po.nl = false; ++wp; } /* print everything as-is */ - po_exp = false; + po.exp = false; } else { - bool new_exp = po_exp, new_nl = po_nl; + bool new_exp = po.exp, new_nl = po.nl; /** * a compromise between sysV and BSD echo commands: @@ -346,8 +366,8 @@ c_print(const char **wp) new_nl = false; goto print_tradparse_ch; case '\0': - po_exp = new_exp; - po_nl = new_nl; + po.exp = new_exp; + po.nl = new_nl; ++wp; goto print_tradparse_arg; } @@ -357,42 +377,42 @@ c_print(const char **wp) /* "print" builtin */ const char *opts = "AnpRrsu,"; const char *emsg; - /* print a "--" argument */ - bool po_pminusminus = false; + + po.pminusminus = false; while ((c = ksh_getopt(wp, &builtin_opt, opts)) != -1) switch (c) { case 'A': - po_char = true; + po.chars = true; break; case 'e': - po_exp = true; + po.exp = true; break; case 'n': - po_nl = false; + po.nl = false; break; case 'p': - if ((fd = coproc_getfd(W_OK, &emsg)) < 0) { + if ((po.fd = coproc_getfd(W_OK, &emsg)) < 0) { bi_errorf(Tf_coproc, emsg); return (1); } break; case 'R': /* fake BSD echo command */ - po_pminusminus = true; - po_exp = false; + po.pminusminus = true; + po.exp = false; opts = "en"; break; case 'r': - po_exp = false; + po.exp = false; break; case 's': - po_hist = true; + po.hist = true; break; case 'u': if (!*(s = builtin_opt.optarg)) - fd = 0; - else if ((fd = check_fd(s, W_OK, &emsg)) < 0) { + po.fd = 0; + else if ((po.fd = check_fd(s, W_OK, &emsg)) < 0) { bi_errorf("-u%s: %s", s, emsg); return (1); } @@ -406,35 +426,33 @@ c_print(const char **wp) if (wp[builtin_opt.optind] && ksh_isdash(wp[builtin_opt.optind])) builtin_opt.optind++; - } else if (po_pminusminus) + } else if (po.pminusminus) builtin_opt.optind--; wp += builtin_opt.optind; } Xinit(xs, xp, 128, ATEMP); - if (*wp != NULL && po_char) { - mksh_ari_t wc; - + if (*wp != NULL && po.chars) { do { - if (!evaluate(*wp, &wc, KSH_RETURN_ERROR, true)) + if (!evaluate(*wp, &po.wc, KSH_RETURN_ERROR, true)) return (1); Xcheck(xs, xp); if (UTFMODE) { - ts[utf_wctomb(ts, wc)] = 0; + po.ts[utf_wctomb(po.ts, po.wc)] = 0; c = 0; do { - Xput(xs, xp, ts[c]); - } while (ts[++c]); + Xput(xs, xp, po.ts[c]); + } while (po.ts[++c]); } else - Xput(xs, xp, wc & 0xFF); + Xput(xs, xp, po.wc & 0xFF); } while (*++wp); } else if (*wp != NULL) { print_read_arg: s = *wp; while ((c = *s++) != '\0') { Xcheck(xs, xp); - if (po_exp && c == '\\') { + if (po.exp && c == '\\') { s_ptr = s; c = unbksl(false, s_get, s_put); s = s_ptr; @@ -442,7 +460,7 @@ c_print(const char **wp) /* rejected by generic function */ switch ((c = *s++)) { case 'c': - po_nl = false; + po.nl = false; /* AT&T brain damage */ continue; case '\0': @@ -454,11 +472,11 @@ c_print(const char **wp) } } else if ((unsigned int)c > 0xFF) { /* generic function returned Unicode */ - ts[utf_wctomb(ts, c - 0x100)] = 0; + po.ts[utf_wctomb(po.ts, c - 0x100)] = 0; c = 0; do { - Xput(xs, xp, ts[c]); - } while (ts[++c]); + Xput(xs, xp, po.ts[c]); + } while (po.ts[++c]); continue; } } @@ -469,18 +487,16 @@ c_print(const char **wp) goto print_read_arg; } } - if (po_nl) + if (po.nl) Xput(xs, xp, '\n'); c = 0; - if (po_hist) { + if (po.hist) { Xput(xs, xp, '\0'); histsave(&source->line, Xstring(xs, xp), HIST_STORE, false); Xfree(xs, xp); } else { size_t len = Xlength(xs, xp); - bool po_coproc = false; - int opipe = 0; /* * Ensure we aren't killed by a SIGPIPE while writing to @@ -488,24 +504,25 @@ c_print(const char **wp) * to just check that the co-process is alive which is * not enough). */ - if (coproc.write >= 0 && coproc.write == fd) { - po_coproc = true; - opipe = block_pipe(); - } + if (coproc.write >= 0 && coproc.write == po.fd) { + po.coproc = true; + po.copipe = block_pipe(); + } else + po.coproc = po.copipe = false; s = Xstring(xs, xp); while (len > 0) { ssize_t nwritten; - if ((nwritten = write(fd, s, len)) < 0) { + if ((nwritten = write(po.fd, s, len)) < 0) { if (errno == EINTR) { - if (po_coproc) - restore_pipe(opipe); + if (po.copipe) + restore_pipe(); /* give the user a chance to ^C out */ intrcheck(); /* interrupted, try again */ - if (po_coproc) - opipe = block_pipe(); + if (po.coproc) + po.copipe = block_pipe(); continue; } c = 1; @@ -514,8 +531,8 @@ c_print(const char **wp) s += nwritten; len -= nwritten; } - if (po_coproc) - restore_pipe(opipe); + if (po.copipe) + restore_pipe(); } return (c); @@ -3721,7 +3738,7 @@ c_cat(const char **wp) ssize_t n, w; const char *fn = ""; char *buf, *cp; - int opipe = 0; + bool opipe; #define MKSH_CAT_BUFSIZ 4096 /* parse options: POSIX demands we support "-u" as no-op */ @@ -3761,7 +3778,8 @@ c_cat(const char **wp) if ((n = blocking_read(fd, (cp = buf), MKSH_CAT_BUFSIZ)) == -1) { if (errno == EINTR) { - restore_pipe(opipe); + if (opipe) + restore_pipe(); /* give the user a chance to ^C out */ intrcheck(); /* interrupted, try again */ @@ -3785,7 +3803,8 @@ c_cat(const char **wp) } if (errno == EINTR) { has_intrsig: - restore_pipe(opipe); + if (opipe) + restore_pipe(); /* give the user a chance to ^C out */ intrcheck(); /* interrupted, try again */ @@ -3811,7 +3830,8 @@ c_cat(const char **wp) } while (*wp); out: - restore_pipe(opipe); + if (opipe) + restore_pipe(); free_osfunc(buf); return (rv); } diff --git a/histrap.c b/histrap.c index c0f87f8..56723ff 100644 --- a/histrap.c +++ b/histrap.c @@ -27,7 +27,7 @@ #include #endif -__RCSID("$MirOS: src/bin/mksh/histrap.c,v 1.158 2016/08/04 20:31:00 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/histrap.c,v 1.159 2016/11/11 18:44:32 tg Exp $"); Trap sigtraps[ksh_NSIG + 1]; static struct sigaction Sigact_ign; @@ -1399,33 +1399,32 @@ settrap(Trap *p, const char *s) } /* - * Called by c_print() when writing to a co-process to ensure SIGPIPE won't - * kill shell (unless user catches it and exits) + * called by c_print() when writing to a co-process to ensure + * SIGPIPE won't kill shell (unless user catches it and exits) */ -int +bool block_pipe(void) { - int restore_dfl = 0; + bool restore_dfl = false; Trap *p = &sigtraps[SIGPIPE]; if (!(p->flags & (TF_ORIG_IGN|TF_ORIG_DFL))) { setsig(p, SIG_IGN, SS_RESTORE_CURR); if (p->flags & TF_ORIG_DFL) - restore_dfl = 1; + restore_dfl = true; } else if (p->cursig == SIG_DFL) { setsig(p, SIG_IGN, SS_RESTORE_CURR); /* restore to SIG_DFL */ - restore_dfl = 1; + restore_dfl = true; } return (restore_dfl); } -/* Called by c_print() to undo whatever block_pipe() did */ +/* called by c_print() to undo whatever block_pipe() did */ void -restore_pipe(int restore_dfl) +restore_pipe(void) { - if (restore_dfl) - setsig(&sigtraps[SIGPIPE], SIG_DFL, SS_RESTORE_CURR); + setsig(&sigtraps[SIGPIPE], SIG_DFL, SS_RESTORE_CURR); } /* From 4ed09871a9f4cbca89b5fe74d3646592f9d603a0 Mon Sep 17 00:00:00 2001 From: tg Date: Fri, 11 Nov 2016 18:50:09 +0000 Subject: [PATCH 16/31] refactor c_print into a loop --- funcs.c | 95 +++++++++++++++++++++++++++++---------------------------- 1 file changed, 48 insertions(+), 47 deletions(-) diff --git a/funcs.c b/funcs.c index 2e1cc7d..7c5a570 100644 --- a/funcs.c +++ b/funcs.c @@ -38,7 +38,7 @@ #endif #endif -__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.307 2016/11/11 18:44:31 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.308 2016/11/11 18:50:09 tg Exp $"); #if HAVE_KILLPG /* @@ -433,58 +433,59 @@ c_print(const char **wp) Xinit(xs, xp, 128, ATEMP); - if (*wp != NULL && po.chars) { - do { - if (!evaluate(*wp, &po.wc, KSH_RETURN_ERROR, true)) - return (1); - Xcheck(xs, xp); - if (UTFMODE) { - po.ts[utf_wctomb(po.ts, po.wc)] = 0; - c = 0; - do { - Xput(xs, xp, po.ts[c]); - } while (po.ts[++c]); - } else - Xput(xs, xp, po.wc & 0xFF); - } while (*++wp); - } else if (*wp != NULL) { - print_read_arg: - s = *wp; - while ((c = *s++) != '\0') { - Xcheck(xs, xp); - if (po.exp && c == '\\') { - s_ptr = s; - c = unbksl(false, s_get, s_put); - s = s_ptr; - if (c == -1) { - /* rejected by generic function */ - switch ((c = *s++)) { - case 'c': - po.nl = false; - /* AT&T brain damage */ - continue; - case '\0': - --s; - c = '\\'; - break; - default: - Xput(xs, xp, '\\'); - } - } else if ((unsigned int)c > 0xFF) { - /* generic function returned Unicode */ - po.ts[utf_wctomb(po.ts, c - 0x100)] = 0; + while (*wp != NULL) { + if (po.chars) { + do { + if (!evaluate(*wp, &po.wc, + KSH_RETURN_ERROR, true)) + return (1); + Xcheck(xs, xp); + if (UTFMODE) { + po.ts[utf_wctomb(po.ts, po.wc)] = 0; c = 0; do { Xput(xs, xp, po.ts[c]); } while (po.ts[++c]); - continue; + } else + Xput(xs, xp, po.wc & 0xFF); + } while (*++wp); + } else { + s = *wp; + while ((c = *s++) != '\0') { + Xcheck(xs, xp); + if (po.exp && c == '\\') { + s_ptr = s; + c = unbksl(false, s_get, s_put); + s = s_ptr; + if (c == -1) { + /* rejected by generic unbksl */ + switch ((c = *s++)) { + case 'c': + po.nl = false; + /* AT&T brain damage */ + continue; + case '\0': + --s; + c = '\\'; + break; + default: + Xput(xs, xp, '\\'); + } + } else if ((unsigned int)c > 0xFF) { + /* unbksl returned Unicode */ + po.ts[utf_wctomb(po.ts, + c - 0x100)] = 0; + c = 0; + do { + Xput(xs, xp, po.ts[c]); + } while (po.ts[++c]); + continue; + } } + Xput(xs, xp, c); } - Xput(xs, xp, c); - } - if (*++wp != NULL) { - Xput(xs, xp, ' '); - goto print_read_arg; + if (*++wp != NULL) + Xput(xs, xp, ' '); } } if (po.nl) From 1c07e75fc0a65bc1c87bfdb642d0da14cc924393 Mon Sep 17 00:00:00 2001 From: tg Date: Fri, 11 Nov 2016 19:02:26 +0000 Subject: [PATCH 17/31] implement: empty arg in print -A is input word separator --- funcs.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/funcs.c b/funcs.c index 7c5a570..b757ddf 100644 --- a/funcs.c +++ b/funcs.c @@ -38,7 +38,7 @@ #endif #endif -__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.308 2016/11/11 18:50:09 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.309 2016/11/11 19:02:26 tg Exp $"); #if HAVE_KILLPG /* @@ -435,8 +435,11 @@ c_print(const char **wp) while (*wp != NULL) { if (po.chars) { - do { - if (!evaluate(*wp, &po.wc, + while (*wp != NULL) { + s = *wp++; + if (*s == '\0') + break; + if (!evaluate(s, &po.wc, KSH_RETURN_ERROR, true)) return (1); Xcheck(xs, xp); @@ -448,9 +451,9 @@ c_print(const char **wp) } while (po.ts[++c]); } else Xput(xs, xp, po.wc & 0xFF); - } while (*++wp); + } } else { - s = *wp; + s = *wp++; while ((c = *s++) != '\0') { Xcheck(xs, xp); if (po.exp && c == '\\') { @@ -484,9 +487,9 @@ c_print(const char **wp) } Xput(xs, xp, c); } - if (*++wp != NULL) - Xput(xs, xp, ' '); } + if (*wp != NULL) + Xput(xs, xp, ' '); } if (po.nl) Xput(xs, xp, '\n'); From d4b81df050993dbc64904a684f6808ac7ee29345 Mon Sep 17 00:00:00 2001 From: tg Date: Fri, 11 Nov 2016 19:09:44 +0000 Subject: [PATCH 18/31] goto keeps us from evaluating the loop condition twice in immediate succession (and shaves off an indentation level) --- funcs.c | 104 +++++++++++++++++++++++++++++--------------------------- 1 file changed, 53 insertions(+), 51 deletions(-) diff --git a/funcs.c b/funcs.c index b757ddf..02e0ed5 100644 --- a/funcs.c +++ b/funcs.c @@ -38,7 +38,7 @@ #endif #endif -__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.309 2016/11/11 19:02:26 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.310 2016/11/11 19:09:44 tg Exp $"); #if HAVE_KILLPG /* @@ -433,64 +433,66 @@ c_print(const char **wp) Xinit(xs, xp, 128, ATEMP); - while (*wp != NULL) { - if (po.chars) { - while (*wp != NULL) { - s = *wp++; - if (*s == '\0') - break; - if (!evaluate(s, &po.wc, - KSH_RETURN_ERROR, true)) - return (1); - Xcheck(xs, xp); - if (UTFMODE) { - po.ts[utf_wctomb(po.ts, po.wc)] = 0; + if (*wp == NULL) + goto print_no_arg; + print_read_arg: + if (po.chars) { + while (*wp != NULL) { + s = *wp++; + if (*s == '\0') + break; + if (!evaluate(s, &po.wc, KSH_RETURN_ERROR, true)) + return (1); + Xcheck(xs, xp); + if (UTFMODE) { + po.ts[utf_wctomb(po.ts, po.wc)] = 0; + c = 0; + do { + Xput(xs, xp, po.ts[c]); + } while (po.ts[++c]); + } else + Xput(xs, xp, po.wc & 0xFF); + } + } else { + s = *wp++; + while ((c = *s++) != '\0') { + Xcheck(xs, xp); + if (po.exp && c == '\\') { + s_ptr = s; + c = unbksl(false, s_get, s_put); + s = s_ptr; + if (c == -1) { + /* rejected by generic function */ + switch ((c = *s++)) { + case 'c': + po.nl = false; + /* AT&T brain damage */ + continue; + case '\0': + --s; + c = '\\'; + break; + default: + Xput(xs, xp, '\\'); + } + } else if ((unsigned int)c > 0xFF) { + /* generic function returned Unicode */ + po.ts[utf_wctomb(po.ts, c - 0x100)] = 0; c = 0; do { Xput(xs, xp, po.ts[c]); } while (po.ts[++c]); - } else - Xput(xs, xp, po.wc & 0xFF); - } - } else { - s = *wp++; - while ((c = *s++) != '\0') { - Xcheck(xs, xp); - if (po.exp && c == '\\') { - s_ptr = s; - c = unbksl(false, s_get, s_put); - s = s_ptr; - if (c == -1) { - /* rejected by generic unbksl */ - switch ((c = *s++)) { - case 'c': - po.nl = false; - /* AT&T brain damage */ - continue; - case '\0': - --s; - c = '\\'; - break; - default: - Xput(xs, xp, '\\'); - } - } else if ((unsigned int)c > 0xFF) { - /* unbksl returned Unicode */ - po.ts[utf_wctomb(po.ts, - c - 0x100)] = 0; - c = 0; - do { - Xput(xs, xp, po.ts[c]); - } while (po.ts[++c]); - continue; - } + continue; } - Xput(xs, xp, c); } + Xput(xs, xp, c); } - if (*wp != NULL) - Xput(xs, xp, ' '); } + if (*wp != NULL) { + Xput(xs, xp, ' '); + goto print_read_arg; + } + print_no_arg: if (po.nl) Xput(xs, xp, '\n'); From 8c2eda2f0fb8e8e2f65163f02fb1730a6c66b4ee Mon Sep 17 00:00:00 2001 From: tg Date: Fri, 11 Nov 2016 19:12:52 +0000 Subject: [PATCH 19/31] implement print -l: change output word separator to newline --- funcs.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/funcs.c b/funcs.c index 02e0ed5..1692822 100644 --- a/funcs.c +++ b/funcs.c @@ -38,7 +38,7 @@ #endif #endif -__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.310 2016/11/11 19:09:44 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.311 2016/11/11 19:12:52 tg Exp $"); #if HAVE_KILLPG /* @@ -291,6 +291,8 @@ c_print(const char **wp) int fd; /* temporary storage for a multibyte character */ char ts[4]; + /* output word separator */ + char ows; /* print trailing newline? */ bool nl; /* expand backslash sequences? */ @@ -307,6 +309,7 @@ c_print(const char **wp) } po; po.fd = 1; + po.ows = ' '; po.nl = true; po.exp = true; po.hist = false; @@ -375,7 +378,7 @@ c_print(const char **wp) } } else { /* "print" builtin */ - const char *opts = "AnpRrsu,"; + const char *opts = "AlnpRrsu,"; const char *emsg; po.pminusminus = false; @@ -388,6 +391,9 @@ c_print(const char **wp) case 'e': po.exp = true; break; + case 'l': + po.ows = '\n'; + break; case 'n': po.nl = false; break; @@ -489,7 +495,7 @@ c_print(const char **wp) } } if (*wp != NULL) { - Xput(xs, xp, ' '); + Xput(xs, xp, po.ows); goto print_read_arg; } print_no_arg: From 6a9dae2144fea2464ac1dbbef9b19aef0f00b201 Mon Sep 17 00:00:00 2001 From: tg Date: Fri, 11 Nov 2016 19:18:40 +0000 Subject: [PATCH 20/31] implement print -N: set output word and line separator to NUL --- funcs.c | 37 +++++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/funcs.c b/funcs.c index 1692822..bd4038f 100644 --- a/funcs.c +++ b/funcs.c @@ -38,7 +38,7 @@ #endif #endif -__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.311 2016/11/11 19:12:52 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.312 2016/11/11 19:18:40 tg Exp $"); #if HAVE_KILLPG /* @@ -292,9 +292,9 @@ c_print(const char **wp) /* temporary storage for a multibyte character */ char ts[4]; /* output word separator */ - char ows; - /* print trailing newline? */ - bool nl; + char ws; + /* output line separator ('!' to not print any) */ + char nl; /* expand backslash sequences? */ bool exp; /* print to history instead of file descriptor / stdout? */ @@ -309,8 +309,8 @@ c_print(const char **wp) } po; po.fd = 1; - po.ows = ' '; - po.nl = true; + po.ws = ' '; + po.nl = '\n'; po.exp = true; po.hist = false; po.chars = false; @@ -336,13 +336,14 @@ c_print(const char **wp) /* Debian Policy 10.4 compliant "echo" builtin */ if (*wp && !strcmp(*wp, "-n")) { /* recognise "-n" only as the first arg */ - po.nl = false; + po.nl = '!'; ++wp; } /* print everything as-is */ po.exp = false; } else { - bool new_exp = po.exp, new_nl = po.nl; + bool new_exp = po.exp; + char new_nl = po.nl; /** * a compromise between sysV and BSD echo commands: @@ -366,7 +367,7 @@ c_print(const char **wp) new_exp = true; goto print_tradparse_ch; case 'n': - new_nl = false; + new_nl = '!'; goto print_tradparse_ch; case '\0': po.exp = new_exp; @@ -378,7 +379,7 @@ c_print(const char **wp) } } else { /* "print" builtin */ - const char *opts = "AlnpRrsu,"; + const char *opts = "AlNnpRrsu,"; const char *emsg; po.pminusminus = false; @@ -392,10 +393,14 @@ c_print(const char **wp) po.exp = true; break; case 'l': - po.ows = '\n'; + po.ws = '\n'; + break; + case 'N': + po.ws = '\0'; + po.nl = '\0'; break; case 'n': - po.nl = false; + po.nl = '!'; break; case 'p': if ((po.fd = coproc_getfd(W_OK, &emsg)) < 0) { @@ -471,7 +476,7 @@ c_print(const char **wp) /* rejected by generic function */ switch ((c = *s++)) { case 'c': - po.nl = false; + po.nl = '!'; /* AT&T brain damage */ continue; case '\0': @@ -495,12 +500,12 @@ c_print(const char **wp) } } if (*wp != NULL) { - Xput(xs, xp, po.ows); + Xput(xs, xp, po.ws); goto print_read_arg; } print_no_arg: - if (po.nl) - Xput(xs, xp, '\n'); + if (po.nl != '!') + Xput(xs, xp, po.nl); c = 0; if (po.hist) { From e16b0b9d5b02ebf5381c791f0d37238f2e9125ee Mon Sep 17 00:00:00 2001 From: tg Date: Fri, 11 Nov 2016 19:59:39 +0000 Subject: [PATCH 21/31] =?UTF-8?q?first=20implementation=20of=20=E2=80=9Cpr?= =?UTF-8?q?int=20-c=E2=80=9D=20for=20columnising,=20currently=20hardcoded?= =?UTF-8?q?=20newlines?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- edit.c | 4 ++-- exec.c | 6 +++--- funcs.c | 42 +++++++++++++++++++++++++++++++++++++++--- 3 files changed, 44 insertions(+), 8 deletions(-) diff --git a/edit.c b/edit.c index dd767ff..548e135 100644 --- a/edit.c +++ b/edit.c @@ -28,7 +28,7 @@ #ifndef MKSH_NO_CMDLINE_EDITING -__RCSID("$MirOS: src/bin/mksh/edit.c,v 1.307 2016/09/01 12:59:08 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/edit.c,v 1.308 2016/11/11 19:59:37 tg Exp $"); /* * in later versions we might use libtermcap for this, but since external @@ -271,7 +271,7 @@ x_print_expansions(int nwords, char * const *words, bool is_command) */ x_putc('\r'); x_putc('\n'); - pr_list(use_copy ? (char **)XPptrv(l) : words); + pr_list(shl_out, use_copy ? (char **)XPptrv(l) : words); if (use_copy) /* not x_free_words() */ diff --git a/exec.c b/exec.c index 11c8a80..666d232 100644 --- a/exec.c +++ b/exec.c @@ -23,7 +23,7 @@ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.182 2016/10/02 22:21:46 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.183 2016/11/11 19:59:39 tg Exp $"); #ifndef MKSH_DEFAULT_EXECSHELL #define MKSH_DEFAULT_EXECSHELL MKSH_UNIXROOT "/bin/sh" @@ -1696,7 +1696,7 @@ plain_fmt_entry(char *buf, size_t buflen, unsigned int i, const void *arg) } void -pr_list(char * const *ap) +pr_list(struct shf *shf, char * const *ap) { size_t acols = 0, aocts = 0, i; unsigned int n; @@ -1711,7 +1711,7 @@ pr_list(char * const *ap) acols = i; } - print_columns(shl_out, n, plain_fmt_entry, (const void *)ap, + print_columns(shf, n, plain_fmt_entry, (const void *)ap, aocts, acols, false); } diff --git a/funcs.c b/funcs.c index bd4038f..4a188f5 100644 --- a/funcs.c +++ b/funcs.c @@ -38,7 +38,7 @@ #endif #endif -__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.312 2016/11/11 19:18:40 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.313 2016/11/11 19:59:39 tg Exp $"); #if HAVE_KILLPG /* @@ -284,6 +284,7 @@ c_print(const char **wp) const char *s; char *xp; XString xs; + XPtrV words; struct { /* temporary storage for a wide character */ mksh_ari_t wc; @@ -297,6 +298,8 @@ c_print(const char **wp) char nl; /* expand backslash sequences? */ bool exp; + /* columnise output? */ + bool col; /* print to history instead of file descriptor / stdout? */ bool hist; /* print words as wide characters? */ @@ -312,6 +315,7 @@ c_print(const char **wp) po.ws = ' '; po.nl = '\n'; po.exp = true; + po.col = false; po.hist = false; po.chars = false; @@ -379,7 +383,7 @@ c_print(const char **wp) } } else { /* "print" builtin */ - const char *opts = "AlNnpRrsu,"; + const char *opts = "AclNnpRrsu,"; const char *emsg; po.pminusminus = false; @@ -389,6 +393,9 @@ c_print(const char **wp) case 'A': po.chars = true; break; + case 'c': + po.col = true; + break; case 'e': po.exp = true; break; @@ -446,6 +453,8 @@ c_print(const char **wp) if (*wp == NULL) goto print_no_arg; + if (po.col) + XPinit(words, 16); print_read_arg: if (po.chars) { while (*wp != NULL) { @@ -499,10 +508,37 @@ c_print(const char **wp) Xput(xs, xp, c); } } + if (po.col) { + Xput(xs, xp, '\0'); + XPput(words, Xclose(xs, xp)); + Xinit(xs, xp, 128, ATEMP); + } if (*wp != NULL) { - Xput(xs, xp, po.ws); + if (!po.col) + Xput(xs, xp, po.ws); goto print_read_arg; } + if (po.col) { + size_t w = XPsize(words); + char *cp; + struct shf shf; + + shf_sopen(NULL, 128, SHF_WR | SHF_DYNAMIC, &shf); + XPput(words, NULL); + pr_list(&shf, (char **)XPptrv(words)); + while (w--) + afree(XPptrv(words)[w], ATEMP); + XPfree(words); + cp = shf_sclose(&shf); + w = strlen(cp); + + XcheckN(xs, xp, w); + memcpy(xp, cp, w); + xp += w; + afree(cp, ATEMP); + + po.nl = '!'; /* for now */ + } print_no_arg: if (po.nl != '!') Xput(xs, xp, po.nl); From 5ba6be5837d4638286cb3c191a0181dc47f24468 Mon Sep 17 00:00:00 2001 From: tg Date: Fri, 11 Nov 2016 20:14:18 +0000 Subject: [PATCH 22/31] put print_columns options into a helper struct, eases passing things around --- edit.c | 7 +++++-- exec.c | 16 +++++++++------- funcs.c | 20 ++++++++++++-------- misc.c | 25 ++++++++++++++----------- 4 files changed, 40 insertions(+), 28 deletions(-) diff --git a/edit.c b/edit.c index 548e135..cb650be 100644 --- a/edit.c +++ b/edit.c @@ -28,7 +28,7 @@ #ifndef MKSH_NO_CMDLINE_EDITING -__RCSID("$MirOS: src/bin/mksh/edit.c,v 1.308 2016/11/11 19:59:37 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/edit.c,v 1.309 2016/11/11 20:14:16 tg Exp $"); /* * in later versions we might use libtermcap for this, but since external @@ -238,6 +238,7 @@ x_print_expansions(int nwords, char * const *words, bool is_command) bool use_copy = false; size_t prefix_len; XPtrV l = { NULL, 0, 0 }; + struct columnise_opts co; /* * Check if all matches are in the same directory (in this @@ -271,7 +272,9 @@ x_print_expansions(int nwords, char * const *words, bool is_command) */ x_putc('\r'); x_putc('\n'); - pr_list(shl_out, use_copy ? (char **)XPptrv(l) : words); + co.shf = shl_out; + co.prefcol = false; + pr_list(&co, use_copy ? (char **)XPptrv(l) : words); if (use_copy) /* not x_free_words() */ diff --git a/exec.c b/exec.c index 666d232..633590d 100644 --- a/exec.c +++ b/exec.c @@ -23,7 +23,7 @@ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.183 2016/11/11 19:59:39 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.184 2016/11/11 20:14:17 tg Exp $"); #ifndef MKSH_DEFAULT_EXECSHELL #define MKSH_DEFAULT_EXECSHELL MKSH_UNIXROOT "/bin/sh" @@ -1656,6 +1656,7 @@ pr_menu(const char * const *ap) const char * const *pp; size_t acols = 0, aocts = 0, i; unsigned int n; + struct columnise_opts co; /* * width/column calculations were done once and saved, but this @@ -1684,9 +1685,10 @@ pr_menu(const char * const *ap) smi.num_width++; smi.args = ap; - print_columns(shl_out, n, select_fmt_entry, (void *)&smi, - smi.num_width + 2 + aocts, smi.num_width + 2 + acols, - true); + co.shf = shl_out; + co.prefcol = true; + print_columns(&co, n, select_fmt_entry, (void *)&smi, + smi.num_width + 2 + aocts, smi.num_width + 2 + acols); } static void @@ -1696,7 +1698,7 @@ plain_fmt_entry(char *buf, size_t buflen, unsigned int i, const void *arg) } void -pr_list(struct shf *shf, char * const *ap) +pr_list(struct columnise_opts *cop, char * const *ap) { size_t acols = 0, aocts = 0, i; unsigned int n; @@ -1711,8 +1713,8 @@ pr_list(struct shf *shf, char * const *ap) acols = i; } - print_columns(shf, n, plain_fmt_entry, (const void *)ap, - aocts, acols, false); + print_columns(cop, n, plain_fmt_entry, (const void *)ap, + aocts, acols); } /* diff --git a/funcs.c b/funcs.c index 4a188f5..64ebf84 100644 --- a/funcs.c +++ b/funcs.c @@ -38,7 +38,7 @@ #endif #endif -__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.313 2016/11/11 19:59:39 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.314 2016/11/11 20:14:17 tg Exp $"); #if HAVE_KILLPG /* @@ -521,15 +521,16 @@ c_print(const char **wp) if (po.col) { size_t w = XPsize(words); char *cp; - struct shf shf; + struct columnise_opts co; - shf_sopen(NULL, 128, SHF_WR | SHF_DYNAMIC, &shf); XPput(words, NULL); - pr_list(&shf, (char **)XPptrv(words)); + co.shf = shf_sopen(NULL, 128, SHF_WR | SHF_DYNAMIC, NULL); + co.prefcol = false; + pr_list(&co, (char **)XPptrv(words)); while (w--) afree(XPptrv(words)[w], ATEMP); XPfree(words); - cp = shf_sclose(&shf); + cp = shf_sclose(co.shf); w = strlen(cp); XcheckN(xs, xp, w); @@ -1495,6 +1496,7 @@ c_kill(const char **wp) ssize_t w, mess_cols = 0, mess_octs = 0; int j = ksh_NSIG - 1; struct kill_info ki = { 0, 0 }; + struct columnise_opts co; do { ki.num_width++; @@ -1512,11 +1514,13 @@ c_kill(const char **wp) mess_cols = w; } - print_columns(shl_stdout, (unsigned int)(ksh_NSIG - 1), + co.shf = shl_stdout; + co.prefcol = true; + + print_columns(&co, (unsigned int)(ksh_NSIG - 1), kill_fmt_entry, (void *)&ki, ki.num_width + 1 + ki.name_width + 1 + mess_octs, - ki.num_width + 1 + ki.name_width + 1 + mess_cols, - true); + ki.num_width + 1 + ki.name_width + 1 + mess_cols); } return (0); } diff --git a/misc.c b/misc.c index 1cdbf6b..2dcc160 100644 --- a/misc.c +++ b/misc.c @@ -30,7 +30,7 @@ #include #endif -__RCSID("$MirOS: src/bin/mksh/misc.c,v 1.245 2016/08/01 18:42:42 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/misc.c,v 1.246 2016/11/11 20:14:18 tg Exp $"); #define KSH_CHVT_FLAG #ifdef MKSH_SMALL @@ -195,6 +195,7 @@ printoptions(bool verbose) if (verbose) { size_t n = 0, len, octs = 0; struct options_info oi; + struct columnise_opts co; /* verbose version */ shf_puts("Current option settings\n", shl_stdout); @@ -211,8 +212,10 @@ printoptions(bool verbose) } ++i; } - print_columns(shl_stdout, n, options_fmt_entry, &oi, - octs + 4, oi.opt_width + 4, true); + co.shf = shl_stdout; + co.prefcol = true; + print_columns(&co, n, options_fmt_entry, &oi, + octs + 4, oi.opt_width + 4); } else { /* short version like AT&T ksh93 */ shf_puts(Tset, shl_stdout); @@ -1226,9 +1229,9 @@ print_value_quoted(struct shf *shf, const char *s) * the i-th element */ void -print_columns(struct shf *shf, unsigned int n, +print_columns(struct columnise_opts *opts, unsigned int n, void (*func)(char *, size_t, unsigned int, const void *), - const void *arg, size_t max_oct, size_t max_colz, bool prefcol) + const void *arg, size_t max_oct, size_t max_colz) { unsigned int i, r, c, rows, cols, nspace, max_col; char *str; @@ -1267,14 +1270,14 @@ print_columns(struct shf *shf, unsigned int n, if (cols < 2) { for (i = 0; i < n; ++i) { (*func)(str, max_oct, i, arg); - shf_puts(str, shf); - shf_putc('\n', shf); + shf_puts(str, opts->shf); + shf_putc('\n', opts->shf); } goto out; } rows = (n + cols - 1) / cols; - if (prefcol && cols > rows) { + if (opts->prefcol && cols > rows) { cols = rows; rows = (n + cols - 1) / cols; } @@ -1289,12 +1292,12 @@ print_columns(struct shf *shf, unsigned int n, break; (*func)(str, max_oct, i, arg); if (i + rows >= n) - shf_puts(str, shf); + shf_puts(str, opts->shf); else - shf_fprintf(shf, "%*s%*s", + shf_fprintf(opts->shf, "%*s%*s", (int)max_col, str, (int)nspace, null); } - shf_putchar('\n', shf); + shf_putchar('\n', opts->shf); } out: afree(str, ATEMP); From 2f63478bc979bc351ec3e35d716d8844bd1e7f77 Mon Sep 17 00:00:00 2001 From: tg Date: Fri, 11 Nov 2016 20:22:52 +0000 Subject: [PATCH 23/31] restructure so that the trailing separator is output separately from the inner line separators --- misc.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/misc.c b/misc.c index 2dcc160..2a30b18 100644 --- a/misc.c +++ b/misc.c @@ -30,7 +30,7 @@ #include #endif -__RCSID("$MirOS: src/bin/mksh/misc.c,v 1.246 2016/11/11 20:14:18 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/misc.c,v 1.247 2016/11/11 20:22:52 tg Exp $"); #define KSH_CHVT_FLAG #ifdef MKSH_SMALL @@ -1233,7 +1233,7 @@ print_columns(struct columnise_opts *opts, unsigned int n, void (*func)(char *, size_t, unsigned int, const void *), const void *arg, size_t max_oct, size_t max_colz) { - unsigned int i, r, c, rows, cols, nspace, max_col; + unsigned int i, r = 0, c, rows, cols, nspace, max_col; char *str; if (!n) @@ -1268,10 +1268,12 @@ print_columns(struct columnise_opts *opts, unsigned int n, /* if we can only print one column anyway, skip the goo */ if (cols < 2) { - for (i = 0; i < n; ++i) { - (*func)(str, max_oct, i, arg); - shf_puts(str, opts->shf); + goto prcols_easy; + while (r < n) { shf_putc('\n', opts->shf); + prcols_easy: + (*func)(str, max_oct, r++, arg); + shf_puts(str, opts->shf); } goto out; } @@ -1286,7 +1288,10 @@ print_columns(struct columnise_opts *opts, unsigned int n, if (nspace < 2) nspace = 2; max_col = -max_col; - for (r = 0; r < rows; r++) { + goto prcols_hard; + while (r < rows) { + shf_putchar('\n', opts->shf); + prcols_hard: for (c = 0; c < cols; c++) { if ((i = c * rows + r) >= n) break; @@ -1297,9 +1302,10 @@ print_columns(struct columnise_opts *opts, unsigned int n, shf_fprintf(opts->shf, "%*s%*s", (int)max_col, str, (int)nspace, null); } - shf_putchar('\n', opts->shf); + ++r; } out: + shf_putchar('\n', opts->shf); afree(str, ATEMP); } From 26689a7c8103e9a2cb44f862988eaabaa6020411 Mon Sep 17 00:00:00 2001 From: tg Date: Fri, 11 Nov 2016 20:53:15 +0000 Subject: [PATCH 24/31] just 'print -c' outputs not even a newline; plug a memleak while here --- funcs.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/funcs.c b/funcs.c index 64ebf84..55aa2a7 100644 --- a/funcs.c +++ b/funcs.c @@ -38,7 +38,7 @@ #endif #endif -__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.314 2016/11/11 20:14:17 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.315 2016/11/11 20:53:15 tg Exp $"); #if HAVE_KILLPG /* @@ -449,12 +449,17 @@ c_print(const char **wp) wp += builtin_opt.optind; } + if (po.col) { + if (*wp == NULL) + return (0); + + XPinit(words, 16); + } + Xinit(xs, xp, 128, ATEMP); if (*wp == NULL) goto print_no_arg; - if (po.col) - XPinit(words, 16); print_read_arg: if (po.chars) { while (*wp != NULL) { @@ -548,7 +553,6 @@ c_print(const char **wp) if (po.hist) { Xput(xs, xp, '\0'); histsave(&source->line, Xstring(xs, xp), HIST_STORE, false); - Xfree(xs, xp); } else { size_t len = Xlength(xs, xp); @@ -588,6 +592,7 @@ c_print(const char **wp) if (po.copipe) restore_pipe(); } + Xfree(xs, xp); return (c); } From 6c04e4a665912191c6ad39b767d27e3277a340d4 Mon Sep 17 00:00:00 2001 From: tg Date: Fri, 11 Nov 2016 21:13:25 +0000 Subject: [PATCH 25/31] make print -c honour line separator --- edit.c | 4 +++- exec.c | 5 +++-- funcs.c | 19 ++++++++----------- misc.c | 12 +++++++----- 4 files changed, 21 insertions(+), 19 deletions(-) diff --git a/edit.c b/edit.c index cb650be..d407d09 100644 --- a/edit.c +++ b/edit.c @@ -28,7 +28,7 @@ #ifndef MKSH_NO_CMDLINE_EDITING -__RCSID("$MirOS: src/bin/mksh/edit.c,v 1.309 2016/11/11 20:14:16 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/edit.c,v 1.310 2016/11/11 21:13:21 tg Exp $"); /* * in later versions we might use libtermcap for this, but since external @@ -273,6 +273,8 @@ x_print_expansions(int nwords, char * const *words, bool is_command) x_putc('\r'); x_putc('\n'); co.shf = shl_out; + co.linesep = '\n'; + co.do_last = true; co.prefcol = false; pr_list(&co, use_copy ? (char **)XPptrv(l) : words); diff --git a/exec.c b/exec.c index 633590d..1a54609 100644 --- a/exec.c +++ b/exec.c @@ -23,7 +23,7 @@ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.184 2016/11/11 20:14:17 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.185 2016/11/11 21:13:23 tg Exp $"); #ifndef MKSH_DEFAULT_EXECSHELL #define MKSH_DEFAULT_EXECSHELL MKSH_UNIXROOT "/bin/sh" @@ -1686,7 +1686,8 @@ pr_menu(const char * const *ap) smi.args = ap; co.shf = shl_out; - co.prefcol = true; + co.linesep = '\n'; + co.prefcol = co.do_last = true; print_columns(&co, n, select_fmt_entry, (void *)&smi, smi.num_width + 2 + aocts, smi.num_width + 2 + acols); } diff --git a/funcs.c b/funcs.c index 55aa2a7..906db32 100644 --- a/funcs.c +++ b/funcs.c @@ -38,7 +38,7 @@ #endif #endif -__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.315 2016/11/11 20:53:15 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.316 2016/11/11 21:13:23 tg Exp $"); #if HAVE_KILLPG /* @@ -525,25 +525,21 @@ c_print(const char **wp) } if (po.col) { size_t w = XPsize(words); - char *cp; struct columnise_opts co; XPput(words, NULL); co.shf = shf_sopen(NULL, 128, SHF_WR | SHF_DYNAMIC, NULL); - co.prefcol = false; + co.linesep = po.nl; + co.prefcol = co.do_last = false; pr_list(&co, (char **)XPptrv(words)); while (w--) afree(XPptrv(words)[w], ATEMP); XPfree(words); - cp = shf_sclose(co.shf); - w = strlen(cp); - + w = co.shf->wp - co.shf->buf; XcheckN(xs, xp, w); - memcpy(xp, cp, w); + memcpy(xp, co.shf->buf, w); xp += w; - afree(cp, ATEMP); - - po.nl = '!'; /* for now */ + shf_sclose(co.shf); } print_no_arg: if (po.nl != '!') @@ -1520,7 +1516,8 @@ c_kill(const char **wp) } co.shf = shl_stdout; - co.prefcol = true; + co.linesep = '\n'; + co.prefcol = co.do_last = true; print_columns(&co, (unsigned int)(ksh_NSIG - 1), kill_fmt_entry, (void *)&ki, diff --git a/misc.c b/misc.c index 2a30b18..36bffcd 100644 --- a/misc.c +++ b/misc.c @@ -30,7 +30,7 @@ #include #endif -__RCSID("$MirOS: src/bin/mksh/misc.c,v 1.247 2016/11/11 20:22:52 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/misc.c,v 1.248 2016/11/11 21:13:25 tg Exp $"); #define KSH_CHVT_FLAG #ifdef MKSH_SMALL @@ -213,7 +213,8 @@ printoptions(bool verbose) ++i; } co.shf = shl_stdout; - co.prefcol = true; + co.linesep = '\n'; + co.prefcol = co.do_last = true; print_columns(&co, n, options_fmt_entry, &oi, octs + 4, oi.opt_width + 4); } else { @@ -1270,7 +1271,7 @@ print_columns(struct columnise_opts *opts, unsigned int n, if (cols < 2) { goto prcols_easy; while (r < n) { - shf_putc('\n', opts->shf); + shf_putc(opts->linesep, opts->shf); prcols_easy: (*func)(str, max_oct, r++, arg); shf_puts(str, opts->shf); @@ -1290,7 +1291,7 @@ print_columns(struct columnise_opts *opts, unsigned int n, max_col = -max_col; goto prcols_hard; while (r < rows) { - shf_putchar('\n', opts->shf); + shf_putchar(opts->linesep, opts->shf); prcols_hard: for (c = 0; c < cols; c++) { if ((i = c * rows + r) >= n) @@ -1305,7 +1306,8 @@ print_columns(struct columnise_opts *opts, unsigned int n, ++r; } out: - shf_putchar('\n', opts->shf); + if (opts->do_last) + shf_putchar(opts->linesep, opts->shf); afree(str, ATEMP); } From 6267ea36a4712a8022629ec9df66997eb2c4cfa4 Mon Sep 17 00:00:00 2001 From: tg Date: Fri, 11 Nov 2016 21:37:35 +0000 Subject: [PATCH 26/31] fix print -cn --- funcs.c | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/funcs.c b/funcs.c index 906db32..22299cd 100644 --- a/funcs.c +++ b/funcs.c @@ -38,7 +38,7 @@ #endif #endif -__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.316 2016/11/11 21:13:23 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.317 2016/11/11 21:37:35 tg Exp $"); #if HAVE_KILLPG /* @@ -294,8 +294,10 @@ c_print(const char **wp) char ts[4]; /* output word separator */ char ws; - /* output line separator ('!' to not print any) */ - char nl; + /* output line separator */ + char ls; + /* output a trailing line separator? */ + bool nl; /* expand backslash sequences? */ bool exp; /* columnise output? */ @@ -313,7 +315,8 @@ c_print(const char **wp) po.fd = 1; po.ws = ' '; - po.nl = '\n'; + po.ls = '\n'; + po.nl = true; po.exp = true; po.col = false; po.hist = false; @@ -340,14 +343,13 @@ c_print(const char **wp) /* Debian Policy 10.4 compliant "echo" builtin */ if (*wp && !strcmp(*wp, "-n")) { /* recognise "-n" only as the first arg */ - po.nl = '!'; + po.nl = false; ++wp; } /* print everything as-is */ po.exp = false; } else { - bool new_exp = po.exp; - char new_nl = po.nl; + bool new_exp = po.exp, new_nl = po.nl; /** * a compromise between sysV and BSD echo commands: @@ -371,7 +373,7 @@ c_print(const char **wp) new_exp = true; goto print_tradparse_ch; case 'n': - new_nl = '!'; + new_nl = false; goto print_tradparse_ch; case '\0': po.exp = new_exp; @@ -404,10 +406,10 @@ c_print(const char **wp) break; case 'N': po.ws = '\0'; - po.nl = '\0'; + po.ls = '\0'; break; case 'n': - po.nl = '!'; + po.nl = false; break; case 'p': if ((po.fd = coproc_getfd(W_OK, &emsg)) < 0) { @@ -490,7 +492,7 @@ c_print(const char **wp) /* rejected by generic function */ switch ((c = *s++)) { case 'c': - po.nl = '!'; + po.nl = false; /* AT&T brain damage */ continue; case '\0': @@ -529,7 +531,7 @@ c_print(const char **wp) XPput(words, NULL); co.shf = shf_sopen(NULL, 128, SHF_WR | SHF_DYNAMIC, NULL); - co.linesep = po.nl; + co.linesep = po.ls; co.prefcol = co.do_last = false; pr_list(&co, (char **)XPptrv(words)); while (w--) @@ -542,8 +544,8 @@ c_print(const char **wp) shf_sclose(co.shf); } print_no_arg: - if (po.nl != '!') - Xput(xs, xp, po.nl); + if (po.nl) + Xput(xs, xp, po.ls); c = 0; if (po.hist) { From 945ef46af16b454f4c609b75f93e3af731131a4c Mon Sep 17 00:00:00 2001 From: tg Date: Fri, 11 Nov 2016 21:37:44 +0000 Subject: [PATCH 27/31] document print builtin changes --- mksh.1 | 77 +++++++++++++++++++++++++++++++++------------------------- 1 file changed, 44 insertions(+), 33 deletions(-) diff --git a/mksh.1 b/mksh.1 index b65ada2..6a1af54 100644 --- a/mksh.1 +++ b/mksh.1 @@ -1,4 +1,4 @@ -.\" $MirOS: src/bin/mksh/mksh.1,v 1.417 2016/09/29 09:04:56 tg Exp $ +.\" $MirOS: src/bin/mksh/mksh.1,v 1.418 2016/11/11 21:37:44 tg Exp $ .\" $OpenBSD: ksh.1,v 1.160 2015/07/04 13:27:04 feinerer Exp $ .\"- .\" Copyright © 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, @@ -76,7 +76,7 @@ .\" with -mandoc, it might implement .Mx itself, but we want to .\" use our own definition. And .Dd must come *first*, always. .\" -.Dd $Mdocdate: September 29 2016 $ +.Dd $Mdocdate: November 11 2016 $ .\" .\" Check which macro package we use, and do other -mdoc setup. .\" @@ -3757,46 +3757,57 @@ however, distributors may have added this as builtin as a speed hack. .Pp .It Xo .Ic print -.Oo Fl Anprsu Ns Oo Ar n Oc \*(Ba +.Oo Fl AclNnprsu Ns Oo Ar n Oc \*(Ba .Fl R Op Fl en Oc .Op Ar argument ... .Xc -.Ic print -prints its arguments on the standard output, separated by spaces and -terminated with a newline. -The -.Fl n -option suppresses the newline. -By default, certain C escapes are translated. -These include these mentioned in +Print the specified argument(s) on the standard output, +separated by spaces, terminated with a newline. +The C escapes mentioned in .Sx Backslash expansion above, as well as .Dq Li \ec , which is equivalent to using the .Fl n -option. -Backslash expansion may be inhibited with the -.Fl r -option. -The -.Fl s -option prints to the history file instead of standard output; the -.Fl u -option prints to file descriptor -.Ar n -.Po -.Ar n -defaults to 1 if omitted -.Pc ; -and the -.Fl p -option prints to the co-process (see +option, are interpreted. +.Pp +The options are as follows: +.Bl -tag -width Ds +.It Fl A +Each +.Ar argument +is arithmetically evaluated; the character corresponding to the +resulting value is printed. +Empty +.Ar argument Ns s +separate input words. +.It Fl c +The output is printed columnised, line by line, similar to how the +.Xr rs 1 +utility, tab completion, the +.Ic kill Fl l +built-in utility and the +.Ic select +statement do. +.It Fl l +Change the output word separator to newline. +.It Fl N +Change the output word and line separator to ASCII NUL. +.It Fl n +Do not print the trailing line separator. +.It Fl p +Print to the co-process (see .Sx Co-processes above). -The -.Fl A -option prints the character corresponding to each -.Ar argument Ns 's value . +.It Fl r +Inhibit backslash expansion. +.It Fl s +Print to the history file instead of standard output. +.It Fl u Op Ar n +Print to the file descriptor +.Ar n Pq defaults to 1 if omitted +instead of standard output. +.El .Pp The .Fl R @@ -6694,7 +6705,7 @@ for the in-memory portion of the history is slow, should use .Xr memmove 3 . .Pp This document attempts to describe -.Nm mksh\ R53 +.Nm mksh\ R54 and up, .\" with vendor patches from insert-your-name-here, compiled without any options impacting functionality, such as From 3aac3c30b5e3771235552e83f87af4f6fee5a389 Mon Sep 17 00:00:00 2001 From: tg Date: Fri, 11 Nov 2016 22:17:09 +0000 Subject: [PATCH 28/31] return 128+SIGALRM if read with timeout timeouts, inspired by GNU bash --- funcs.c | 19 +++++++++---------- mksh.1 | 11 ++++++++--- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/funcs.c b/funcs.c index 22299cd..2e5f44c 100644 --- a/funcs.c +++ b/funcs.c @@ -38,7 +38,7 @@ #endif #endif -__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.317 2016/11/11 21:37:35 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.318 2016/11/11 22:17:08 tg Exp $"); #if HAVE_KILLPG /* @@ -2085,7 +2085,7 @@ c_read(const char **wp) timersub(&tvlim, &tv, &tv); if (tv.tv_sec < 0) { /* timeout expired globally */ - rv = 1; + rv = 3; goto c_read_out; } @@ -2095,8 +2095,8 @@ c_read(const char **wp) case 0: /* timeout expired for this call */ bytesread = 0; - /* fake EOF read; all cases return 1 */ - goto c_read_didread; + rv = 3; + goto c_read_readdone; default: bi_errorf(Tf_sD_s, Tselect, cstrerror(errno)); rv = 2; @@ -2121,7 +2121,6 @@ c_read(const char **wp) goto c_read_out; } - c_read_didread: switch (readmode) { case READALL: if (bytesread == 0) { @@ -2195,13 +2194,13 @@ c_read(const char **wp) /*- * state: we finished reading the input and NUL terminated it * Xstring(xs, xp) -> xp-1 = input string without trailing delim - * rv = 1 if EOF, 0 otherwise (errors handled already) + * rv = 3 if timeout, 1 if EOF, 0 otherwise (errors handled already) */ - if (rv == 1) { - /* clean up coprocess if needed, on EOF */ + if (rv) { + /* clean up coprocess if needed, on EOF/error/timeout */ coproc_read_close(fd); - if (readmode == READALL) + if (readmode == READALL && (rv == 1 || (rv == 3 && bytesread))) /* EOF is no error here */ rv = 0; } @@ -2367,7 +2366,7 @@ c_read(const char **wp) Xfree(xs, xp); if (restore_tios) mksh_tcset(fd, &tios); - return (rv); + return (rv == 3 ? ksh_sigmask(SIGALRM) : rv); #undef is_ifsws } diff --git a/mksh.1 b/mksh.1 index 6a1af54..51ba3fc 100644 --- a/mksh.1 +++ b/mksh.1 @@ -1,4 +1,4 @@ -.\" $MirOS: src/bin/mksh/mksh.1,v 1.418 2016/11/11 21:37:44 tg Exp $ +.\" $MirOS: src/bin/mksh/mksh.1,v 1.419 2016/11/11 22:17:09 tg Exp $ .\" $OpenBSD: ksh.1,v 1.160 2015/07/04 13:27:04 feinerer Exp $ .\"- .\" Copyright © 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, @@ -3912,7 +3912,10 @@ if empty, instead of the ASCII newline character as input line delimiter. Instead of reading till end-of-line, read exactly .Ar z bytes. -If EOF or a timeout occurs, a partial read is returned with exit status 1. +Upon EOF, a partial read is returned with exit status 1. +After timeout, a partial read is returned with an exit status as if +.Dv SIGALRM +were caught. .It Fl n Ar z Instead of reading till end-of-line, read up to .Ar z @@ -3933,7 +3936,9 @@ Interrupt reading after seconds (specified as positive decimal value with an optional fractional part). The exit status of .Nm read -is 1 if the timeout occurred, but partial reads may still be returned. +is the same as if +.Dv SIGALRM +were caught if the timeout occurred, but partial reads may still be returned. .It Fl r Normally, the ASCII backslash character escapes the special meaning of the following character and is stripped from the input; From 7b4bee7e58f76d1875496c044902eb2077e5761e Mon Sep 17 00:00:00 2001 From: tg Date: Fri, 11 Nov 2016 23:31:39 +0000 Subject: [PATCH 29/31] collective R54 release preparation multi-merger: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit install both lksh and mksh manpages from Build.sh (Martijn Dekker) spelling fixes (Larry Hynes) manpage improvements (Martijn Dekker) initial port to Harvey-OS’ APEX (Ronald G. Minnich, Elbing Miss, Álvaro Jurado) more from komh’s OS/2 port (KO Myung-Hun) --- Build.sh | 42 ++++++++++++++++++++++++++++++++---------- Makefile | 4 ++-- check.t | 8 ++++---- edit.c | 31 +++++++++++++++++-------------- eval.c | 14 +++++++------- exec.c | 14 +++++++++----- lksh.1 | 8 ++++---- main.c | 4 ++-- misc.c | 32 +++++++++++++++++++------------- mksh.1 | 34 +++++++++++++++++----------------- sh.h | 44 ++++++++++++++++++++++++++++++++------------ var.c | 25 +++++++++++++++++++++++-- var_spec.h | 11 ++++++++++- 13 files changed, 178 insertions(+), 93 deletions(-) diff --git a/Build.sh b/Build.sh index 915aa8f..d0ff130 100644 --- a/Build.sh +++ b/Build.sh @@ -1,5 +1,5 @@ #!/bin/sh -srcversion='$MirOS: src/bin/mksh/Build.sh,v 1.706 2016/11/07 16:55:51 tg Exp $' +srcversion='$MirOS: src/bin/mksh/Build.sh,v 1.707 2016/11/11 23:31:29 tg Exp $' #- # Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, # 2011, 2012, 2013, 2014, 2015, 2016 @@ -584,7 +584,7 @@ if test -d $tfn || test -d $tfn.exe; then exit 1 fi rmf a.exe* a.out* conftest.c conftest.exe* *core core.* ${tfn}* *.bc *.dbg \ - *.ll *.o *.gen Rebuild.sh lft no signames.inc test.sh x vv.out + *.ll *.o *.gen *.cat1 Rebuild.sh lft no signames.inc test.sh x vv.out SRCS="lalloc.c eval.c exec.c expr.c funcs.c histrap.c jobs.c" SRCS="$SRCS lex.c main.c misc.c shf.c syn.c tree.c var.c" @@ -755,6 +755,24 @@ GNU/kFreeBSD) Haiku) add_cppflags -DMKSH_ASSUME_UTF8; HAVE_ISSET_MKSH_ASSUME_UTF8=1 ;; +Harvey) + add_cppflags -D_POSIX_SOURCE + add_cppflags -D_LIMITS_EXTENSION + add_cppflags -D_BSD_EXTENSION + add_cppflags -D_SUSV2_SOURCE + add_cppflags -D_GNU_SOURCE + add_cppflags -DMKSH_ASSUME_UTF8; HAVE_ISSET_MKSH_ASSUME_UTF8=1 + add_cppflags -DMKSH_NO_CMDLINE_EDITING + add_cppflags -DMKSH__NO_SETEUGID + oswarn=' and will currently not work' + add_cppflags -DMKSH_UNEMPLOYED + add_cppflags -DMKSH_NOPROSPECTOFWORK + # these taken from Harvey-OS github and need re-checking + add_cppflags -D_setjmp=setjmp -D_longjmp=longjmp + : "${HAVE_CAN_NO_EH_FRAME=0}" + : "${HAVE_CAN_FNOSTRICTALIASING=0}" + : "${HAVE_CAN_FSTACKPROTECTORSTRONG=0}" + ;; HP-UX) ;; Interix) @@ -833,12 +851,14 @@ OpenBSD) OS/2) HAVE_TERMIOS_H=0 HAVE_MKNOD=0 # setmode() incompatible - oswarn="; it is currently being ported" + oswarn="; it is currently being ported, get it from" + oswarn="$oswarn${nl}https://github.com/komh/mksh-os2 in the meanwhile" check_categories="$check_categories nosymlink" : "${CC=gcc}" : "${SIZE=: size}" add_cppflags -DMKSH_UNEMPLOYED add_cppflags -DMKSH_NOPROSPECTOFWORK + add_cppflags -DMKSH_NO_LIMITS ;; OSF1) HAVE_SIG_T=0 # incompatible @@ -2347,7 +2367,7 @@ addsrcs '!' HAVE_STRLCPY strlcpy.c addsrcs USE_PRINTF_BUILTIN printf.c test 1 = "$USE_PRINTF_BUILTIN" && add_cppflags -DMKSH_PRINTF_BUILTIN test 1 = "$HAVE_CAN_VERB" && CFLAGS="$CFLAGS -verbose" -add_cppflags -DMKSH_BUILD_R=539 +add_cppflags -DMKSH_BUILD_R=541 $e $bi$me: Finished configuration testing, now producing output.$ao @@ -2593,8 +2613,8 @@ esac tcfn=$mkshexe test $cm = combine || v "$CC $CFLAGS $LDFLAGS -o $tcfn $lobjs $LIBS $ccpr" test -f $tcfn || exit 1 -test 1 = $r || v "$NROFF -mdoc <'$srcdir/mksh.1' >$tfn.cat1" || \ - rmf $tfn.cat1 +test 1 = $r || v "$NROFF -mdoc <'$srcdir/lksh.1' >lksh.cat1" || rmf lksh.cat1 +test 1 = $r || v "$NROFF -mdoc <'$srcdir/mksh.1' >mksh.cat1" || rmf mksh.cat1 test 0 = $eq && v $SIZE $tcfn i=install test -f /usr/ucb/$i && i=/usr/ucb/$i @@ -2608,12 +2628,14 @@ if test $legacy = 0; then fi $e $e Installing the manual: -if test -f $tfn.cat1; then - $e "# $i -c -o root -g bin -m 444 $tfn.cat1" \ - "/usr/share/man/cat1/$tfn.0" +if test -f mksh.cat1; then + $e "# $i -c -o root -g bin -m 444 lksh.cat1" \ + "/usr/share/man/cat1/lksh.0" + $e "# $i -c -o root -g bin -m 444 mksh.cat1" \ + "/usr/share/man/cat1/mksh.0" $e or fi -$e "# $i -c -o root -g bin -m 444 $tfn.1 /usr/share/man/man1/$tfn.1" +$e "# $i -c -o root -g bin -m 444 lksh.1 mksh.1 /usr/share/man/man1/" $e $e Run the regression test suite: ./test.sh $e Please also read the sample file dot.mkshrc and the fine manual. diff --git a/Makefile b/Makefile index 4165e92..b1fd33a 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -# $MirOS: src/bin/mksh/Makefile,v 1.153 2016/11/07 16:58:45 tg Exp $ +# $MirOS: src/bin/mksh/Makefile,v 1.154 2016/11/11 23:31:30 tg Exp $ #- # Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, # 2011, 2012, 2013, 2014, 2015, 2016 @@ -57,7 +57,7 @@ CPPFLAGS+= -DMKSH_ASSUME_UTF8 -DMKSH_DISABLE_DEPRECATED \ -DHAVE_SETGROUPS=1 -DHAVE_STRERROR=0 -DHAVE_STRSIGNAL=0 \ -DHAVE_STRLCPY=1 -DHAVE_FLOCK_DECL=1 -DHAVE_REVOKE_DECL=1 \ -DHAVE_SYS_ERRLIST_DECL=1 -DHAVE_SYS_SIGLIST_DECL=1 \ - -DHAVE_PERSISTENT_HISTORY=1 -DMKSH_BUILD_R=539 + -DHAVE_PERSISTENT_HISTORY=1 -DMKSH_BUILD_R=541 CPPFLAGS+= -D${${PROG:L}_tf:C/(Mir${MAN:E}{0,1}){2}/4/:S/x/mksh_BUILD/:U} CPPFLAGS+= -I. COPTS+= -std=c89 -Wall diff --git a/check.t b/check.t index 6f86dc5..1b03af6 100644 --- a/check.t +++ b/check.t @@ -1,4 +1,4 @@ -# $MirOS: src/bin/mksh/check.t,v 1.755 2016/11/07 16:58:45 tg Exp $ +# $MirOS: src/bin/mksh/check.t,v 1.756 2016/11/11 23:31:31 tg Exp $ # -*- mode: sh -*- #- # 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 expected-stdout: - @(#)MIRBSD KSH R53 2016/11/07 + @(#)MIRBSD KSH R54 2016/11/11 description: Check version of shell. stdin: @@ -39,7 +39,7 @@ name: KSH_VERSION category: shell:legacy-no --- expected-stdout: - @(#)LEGACY KSH R53 2016/11/07 + @(#)LEGACY KSH R54 2016/11/11 description: Check version of legacy shell. stdin: @@ -4948,7 +4948,7 @@ name: integer-base-check-flat description: Check behaviour does not match POSuX (except if set -o posix), because a not type-safe scripting language has *no* business - interpreting the string "010" as octal numer eight (dangerous). + interpreting the string "010" as octal number eight (dangerous). stdin: echo 1 "$("$__progname" -c 'echo :$((10))/$((010)),$((0x10)):')" . echo 2 "$("$__progname" -o posix -c 'echo :$((10))/$((010)),$((0x10)):')" . diff --git a/edit.c b/edit.c index d407d09..163dfe0 100644 --- a/edit.c +++ b/edit.c @@ -28,7 +28,7 @@ #ifndef MKSH_NO_CMDLINE_EDITING -__RCSID("$MirOS: src/bin/mksh/edit.c,v 1.310 2016/11/11 21:13:21 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/edit.c,v 1.311 2016/11/11 23:31:33 tg Exp $"); /* * in later versions we might use libtermcap for this, but since external @@ -258,7 +258,8 @@ x_print_expansions(int nwords, char * const *words, bool is_command) break; /* All in same directory? */ if (i == nwords) { - while (prefix_len > 0 && words[0][prefix_len - 1] != '/') + while (prefix_len > 0 && + !mksh_cdirsep(words[0][prefix_len - 1])) prefix_len--; use_copy = true; XPinit(l, nwords + 1); @@ -338,7 +339,7 @@ x_glob_hlp_tilde_and_rem_qchar(char *s, bool magic_flag) * and if so, discern "~foo/bar" and "~/baz" from "~blah"; * if we have a directory part (the former), try to expand */ - if (*s == '~' && (cp = strchr(s, '/')) != NULL) { + if (*s == '~' && (cp = mksh_sdirsep(s)) != NULL) { /* ok, so split into "~foo"/"bar" or "~"/"baz" */ *cp++ = 0; /* try to expand the tilde */ @@ -593,7 +594,7 @@ x_locate_word(const char *buf, int buflen, int pos, int *startp, * like file globbing. */ for (p = start; p < end; p++) - if (buf[p] == '/') + if (mksh_cdirsep(buf[p])) break; iscmd = p == end; } @@ -657,7 +658,7 @@ x_cf_glob(int *flagsp, const char *buf, int buflen, int pos, int *startp, } } - if (*toglob == '~' && !vstrchr(toglob, '/')) { + if (*toglob == '~' && !mksh_vdirsep(toglob)) { /* neither for '~foo' (but '~foo/bar') */ *flagsp |= XCF_IS_NOSPACE; goto dont_add_glob; @@ -746,13 +747,15 @@ x_basename(const char *s, const char *se) if (s == se) return (0); - /* Skip trailing slashes */ - for (p = se - 1; p > s && *p == '/'; p--) - ; - for (; p > s && *p != '/'; p--) - ; - if (*p == '/' && p + 1 < se) - p++; + /* skip trailing directory separators */ + p = se - 1; + while (p > s && mksh_cdirsep(*p)) + --p; + /* drop last component */ + while (p > s && !mksh_cdirsep(*p)) + --p; + if (mksh_cdirsep(*p) && p + 1 < se) + ++p; return (p - s); } @@ -2783,7 +2786,7 @@ do_complete( * append a space if this is a single non-directory match * and not a parameter or homedir substitution */ - if (nwords == 1 && words[0][nlen - 1] != '/' && + if (nwords == 1 && !mksh_cdirsep(words[0][nlen - 1]) && !(flags & XCF_IS_NOSPACE)) { x_ins(T1space); } @@ -5404,7 +5407,7 @@ complete_word(int cmd, int count) * append a space if this is a non-directory match * and not a parameter or homedir substitution */ - if (match_len > 0 && match[match_len - 1] != '/' && + if (match_len > 0 && !mksh_cdirsep(match[match_len - 1]) && !(flags & XCF_IS_NOSPACE)) rval = putbuf(T1space, 1, false); } diff --git a/eval.c b/eval.c index bc77a54..a9980c7 100644 --- a/eval.c +++ b/eval.c @@ -23,7 +23,7 @@ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.193 2016/09/01 12:59:09 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.194 2016/11/11 23:31:34 tg Exp $"); /* * string expansion @@ -1576,7 +1576,7 @@ globit(XString *xs, /* dest string */ * SunOS 4.1.3 does this... */ if ((check & GF_EXCHECK) && xp > Xstring(*xs, xp) && - xp[-1] == '/' && !S_ISDIR(lstatb.st_mode) && + mksh_cdirsep(xp[-1]) && !S_ISDIR(lstatb.st_mode) && (!S_ISLNK(lstatb.st_mode) || stat_check() < 0 || !S_ISDIR(statb.st_mode))) return; @@ -1586,7 +1586,7 @@ globit(XString *xs, /* dest string */ * directory */ if (((check & GF_MARKDIR) && (check & GF_GLOBBED)) && - xp > Xstring(*xs, xp) && xp[-1] != '/' && + xp > Xstring(*xs, xp) && !mksh_cdirsep(xp[-1]) && (S_ISDIR(lstatb.st_mode) || (S_ISLNK(lstatb.st_mode) && stat_check() > 0 && S_ISDIR(statb.st_mode)))) { @@ -1601,11 +1601,11 @@ globit(XString *xs, /* dest string */ if (xp > Xstring(*xs, xp)) *xp++ = '/'; - while (*sp == '/') { + while (mksh_cdirsep(*sp)) { Xcheck(*xs, xp); *xp++ = *sp++; } - np = strchr(sp, '/'); + np = mksh_sdirsep(sp); if (np != NULL) { se = np; /* don't assume '/', can be multiple kinds */ @@ -1713,8 +1713,8 @@ maybe_expand_tilde(const char *p, XString *dsp, char **dpp, bool isassign) Xinit(ts, tp, 16, ATEMP); /* : only for DOASNTILDE form */ - while (p[0] == CHAR && p[1] != '/' && (!isassign || p[1] != ':')) - { + while (p[0] == CHAR && !mksh_cdirsep(p[1]) && + (!isassign || p[1] != ':')) { Xcheck(ts, tp); *tp++ = p[1]; p += 2; diff --git a/exec.c b/exec.c index 1a54609..882b628 100644 --- a/exec.c +++ b/exec.c @@ -23,7 +23,7 @@ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.185 2016/11/11 21:13:23 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.186 2016/11/11 23:31:34 tg Exp $"); #ifndef MKSH_DEFAULT_EXECSHELL #define MKSH_DEFAULT_EXECSHELL MKSH_UNIXROOT "/bin/sh" @@ -672,7 +672,7 @@ comexec(struct op *t, struct tbl * volatile tp, const char **ap, rv = subst_exstat; goto Leave; } else if (!tp) { - if (Flag(FRESTRICTED) && vstrchr(cp, '/')) { + if (Flag(FRESTRICTED) && mksh_vdirsep(cp)) { warningf(true, Tf_sD_s, cp, "restricted"); rv = 1; goto Leave; @@ -1123,7 +1123,7 @@ findcom(const char *name, int flags) char *fpath; union mksh_cchack npath; - if (vstrchr(name, '/')) { + if (mksh_vdirsep(name)) { insert = 0; /* prevent FPATH search below */ flags &= ~FC_FUNC; @@ -1240,8 +1240,12 @@ search_access(const char *fn, int mode) eno = errno; return (eno ? eno : EACCES); } +#ifdef __OS2__ + /* treat all files as executable on OS/2 */ + sb.st_mode &= S_IXUSR | S_IXGRP | S_IXOTH; +#endif if (mode == X_OK && (!S_ISREG(sb.st_mode) || - !(sb.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH)))) + !(sb.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)))) /* access(2) may say root can execute everything */ return (S_ISDIR(sb.st_mode) ? EISDIR : EACCES); return (0); @@ -1263,7 +1267,7 @@ search_path(const char *name, const char *lpath, size_t namelen; int ec = 0, ev; - if (vstrchr(name, '/')) { + if (mksh_vdirsep(name)) { if ((ec = search_access(name, mode)) == 0) { search_path_ok: if (errnop) diff --git a/lksh.1 b/lksh.1 index 8d297b7..a9f8be7 100644 --- a/lksh.1 +++ b/lksh.1 @@ -1,4 +1,4 @@ -.\" $MirOS: src/bin/mksh/lksh.1,v 1.19 2016/08/25 16:21:33 tg Exp $ +.\" $MirOS: src/bin/mksh/lksh.1,v 1.20 2016/11/11 23:31:35 tg Exp $ .\"- .\" Copyright (c) 2008, 2009, 2010, 2012, 2013, 2015, 2016 .\" mirabilos @@ -74,7 +74,7 @@ .\" with -mandoc, it might implement .Mx itself, but we want to .\" use our own definition. And .Dd must come *first*, always. .\" -.Dd $Mdocdate: August 25 2016 $ +.Dd $Mdocdate: November 11 2016 $ .\" .\" Check which macro package we use, and do other -mdoc setup. .\" @@ -221,8 +221,8 @@ for the versions this document applies to. .Nm uses .Tn POSIX -arithmetics, which has quite a few implications: -The data type for arithmetics is the host +arithmetic, which has quite a few implications: +The data type for arithmetic operations is the host .Tn ISO C .Vt long diff --git a/main.c b/main.c index 090a85c..1a983f1 100644 --- a/main.c +++ b/main.c @@ -34,7 +34,7 @@ #include #endif -__RCSID("$MirOS: src/bin/mksh/main.c,v 1.320 2016/10/26 22:55:51 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/main.c,v 1.321 2016/11/11 23:31:35 tg Exp $"); extern char **environ; @@ -227,7 +227,7 @@ main_init(int argc, const char *argv[], Source **sp, struct block **lp) ccp = kshname; goto begin_parsing_kshname; while ((i = ccp[argi++])) { - if (i == '/') { + if (mksh_cdirsep(i)) { ccp += argi; begin_parsing_kshname: argi = 0; diff --git a/misc.c b/misc.c index 36bffcd..647d1d1 100644 --- a/misc.c +++ b/misc.c @@ -30,7 +30,7 @@ #include #endif -__RCSID("$MirOS: src/bin/mksh/misc.c,v 1.248 2016/11/11 21:13:25 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/misc.c,v 1.249 2016/11/11 23:31:35 tg Exp $"); #define KSH_CHVT_FLAG #ifdef MKSH_SMALL @@ -391,7 +391,7 @@ parse_args(const char **argv, */ if (*p != '-') for (q = p; *q; ) - if (*q++ == '/') + if (mksh_cdirsep(*q++)) p = q; Flag(FLOGIN) = (*p == '-'); opts = cmd_opts; @@ -1443,14 +1443,14 @@ do_realpath(const char *upath) while (*ip) { /* skip slashes in input */ - while (*ip == '/') + while (mksh_cdirsep(*ip)) ++ip; if (!*ip) break; /* get next pathname component from input */ tp = ip; - while (*ip && *ip != '/') + while (*ip && !mksh_cdirsep(*ip)) ++ip; len = ip - tp; @@ -1462,7 +1462,7 @@ do_realpath(const char *upath) else if (len == 2 && tp[1] == '.') { /* strip off last pathname component */ while (xp > Xstring(xs, xp)) - if (*--xp == '/') + if (mksh_cdirsep(*--xp)) break; /* then continue with the next one */ continue; @@ -1485,7 +1485,7 @@ do_realpath(const char *upath) /* lstat failed */ if (errno == ENOENT) { /* because the pathname does not exist */ - while (*ip == '/') + while (mksh_cdirsep(*ip)) /* skip any trailing slashes */ ++ip; /* no more components left? */ @@ -1545,6 +1545,7 @@ do_realpath(const char *upath) /* assert: xp == xs.beg => start of path */ /* exactly two leading slashes? (SUSv4 3.266) */ + /* @komh do NOT use mksh_cdirsep() here */ if (ip[1] == '/' && ip[2] != '/') { /* keep them, e.g. for UNC pathnames */ Xput(xs, xp, '/'); @@ -1570,7 +1571,7 @@ do_realpath(const char *upath) * if source path had a trailing slash, check if target path * is not a non-directory existing file */ - if (ip > ipath && ip[-1] == '/') { + if (ip > ipath && mksh_cdirsep(ip[-1])) { if (stat(Xstring(xs, xp), &sb)) { if (errno != ENOENT) goto notfound; @@ -1639,7 +1640,7 @@ make_path(const char *cwd, const char *file, if (c == '.') c = file[2]; - if (c == '/' || c == '\0') + if (mksh_cdirsep(c) || c == '\0') use_cdpath = false; } @@ -1661,7 +1662,7 @@ make_path(const char *cwd, const char *file, XcheckN(*xsp, xp, len); memcpy(xp, cwd, len); xp += len; - if (cwd[len - 1] != '/') + if (!mksh_cdirsep(cwd[len - 1])) Xput(*xsp, xp, '/'); } *phys_pathp = Xlength(*xsp, xp); @@ -1669,7 +1670,7 @@ make_path(const char *cwd, const char *file, XcheckN(*xsp, xp, plen); memcpy(xp, plist, plen); xp += plen; - if (plist[plen - 1] != '/') + if (!mksh_cdirsep(plist[plen - 1])) Xput(*xsp, xp, '/'); rval = 1; } @@ -1711,9 +1712,14 @@ simplify_path(char *p) return; case '/': /* exactly two leading slashes? (SUSv4 3.266) */ + /* @komh no mksh_cdirsep() here! */ if (p[1] == '/' && p[2] != '/') /* keep them, e.g. for UNC pathnames */ ++p; +#ifdef __OS2__ + /* FALLTHROUGH */ + case '\\': +#endif needslash = true; break; default: @@ -1723,14 +1729,14 @@ simplify_path(char *p) while (*ip) { /* skip slashes in input */ - while (*ip == '/') + while (mksh_cdirsep(*ip)) ++ip; if (!*ip) break; /* get next pathname component from input */ tp = ip; - while (*ip && *ip != '/') + while (*ip && !mksh_cdirsep(*ip)) ++ip; len = ip - tp; @@ -1750,7 +1756,7 @@ simplify_path(char *p) strip_last_component: /* strip off last pathname component */ while (dp > sp) - if (*--dp == '/') + if (mksh_cdirsep(*--dp)) break; } else { /* relative path, at its beginning */ diff --git a/mksh.1 b/mksh.1 index 51ba3fc..0de2b8f 100644 --- a/mksh.1 +++ b/mksh.1 @@ -1,4 +1,4 @@ -.\" $MirOS: src/bin/mksh/mksh.1,v 1.419 2016/11/11 22:17:09 tg Exp $ +.\" $MirOS: src/bin/mksh/mksh.1,v 1.420 2016/11/11 23:31:36 tg Exp $ .\" $OpenBSD: ksh.1,v 1.160 2015/07/04 13:27:04 feinerer Exp $ .\"- .\" Copyright © 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, @@ -1060,7 +1060,7 @@ For and .Dq Li \eu#### , .Dq # -means a hexadecimal digit, of thich there may be none up to four or eight; +means a hexadecimal digit, of which there may be none up to four or eight; these escapes translate a Unicode codepoint to UTF-8. Furthermore, .Dq Li \eE @@ -2602,7 +2602,7 @@ This also affects implicit conversion to integer, for example as done by the .Ic let command. .Em Never -use unchecked user input, e.g. from the environment, in arithmetics! +use unchecked user input, e.g. from the environment, in an arithmetic context! .Pp Expressions are calculated using signed arithmetic and the .Vt mksh_ari_t @@ -4899,7 +4899,7 @@ If necessary, values are either truncated or space padded to fit the field width. .It Fl l Lower case attribute. -All upper case characters in values are converted to lower case. +All upper case ASCII characters in values are converted to lower case. (In the original Korn shell, this parameter meant .Dq long integer when used with the @@ -4923,7 +4923,7 @@ is lazily evaluated at the time .Ar name is accessed. This can be used by functions to access variables whose names are -passed as parametres, instead of using +passed as parameters, instead of using .Ic eval . .It Fl p Print complete @@ -4964,7 +4964,7 @@ option). This option is not in the original Korn shell. .It Fl u Upper case attribute. -All lower case characters in values are converted to upper case. +All lower case ASCII characters in values are converted to upper case. (In the original Korn shell, this parameter meant .Dq unsigned integer when used with the @@ -5381,11 +5381,11 @@ to behave even more compliant in places where the defaults or opinions differ. Note that .Nm mksh -will still operate with unsigned 32-bit arithmetics; use +will still operate with unsigned 32-bit arithmetic; use .Nm lksh -if arithmetics on the host +if arithmetic on the host .Vt long -data type, complete with ISO C Undefined Behaviour, are required; +data type, complete with ISO C Undefined Behaviour, is required; refer to the .Xr lksh 1 manual page for details. @@ -5586,7 +5586,7 @@ Moves the cursor to the beginning of the edited input line. .Op Ar n .No \*(ha[C , \*(ha[c .Xc -Uppercase the first character in the next +Uppercase the first ASCII character in the next .Ar n words, leaving the cursor past the end of the last word. .It clear\-screen: \*(ha[\*(haL @@ -6586,8 +6586,8 @@ This shell is based on the public domain 7th edition Bourne shell clone by .An Charles Forsyth , who kindly agreed to, in countries where the Public Domain status of the work may not be valid, grant a copyright licence to the general public to deal in -the work without restriction and permission to sublicence derivates under the -terms of any (OSI approved) Open Source licence, +the work without restriction and permission to sublicence derivatives under +the terms of any (OSI approved) Open Source licence, and parts of the BRL shell by .An Doug A. Gwyn , .An Doug Kingston , @@ -6629,7 +6629,7 @@ The complete legalese is at: has a different scope model from .At .Nm ksh , -which leads to subtile differences in semantics for identical builtins. +which leads to subtle differences in semantics for identical builtins. This can cause issues with a .Ic nameref to suddenly point to a local variable by accident; fixing this is hard. @@ -6644,9 +6644,9 @@ foo \*(Ba bar \*(Ba& read \-p baz # will, however, do so .Ed .Pp .Nm mksh -provides a consistent set of 32-bit integer arithmetics, both signed -and unsigned, with defined wraparound and sign of the result of a -remainder operation, even (defying POSIX) on 36-bit and 64-bit systems. +provides a consistent 32-bit integer arithmetic implementation, both +signed and unsigned, with sign of the result of a remainder operation +and wraparound defined, even (defying POSIX) on 36-bit and 64-bit systems. .Pp .Nm mksh provides a consistent, clear interface normally. @@ -6701,7 +6701,7 @@ The truncation process involved when changing .Ev HISTFILE does not free old history entries (leaks memory) and leaks old entries into the new history if their line numbers are -not overwritten by same-numer entries from the persistent +not overwritten by same-number entries from the persistent history file; truncating the on-disc file to .Ev HISTSIZE lines has always been broken and prone to history file corruption diff --git a/sh.h b/sh.h index dabb074..c9b9078 100644 --- a/sh.h +++ b/sh.h @@ -175,9 +175,9 @@ #endif #ifdef EXTERN -__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.790 2016/11/07 16:58:48 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.791 2016/11/11 23:31:38 tg Exp $"); #endif -#define MKSH_VERSION "R53 2016/11/07" +#define MKSH_VERSION "R54 2016/11/11" /* arithmetic types: C implementation */ #if !HAVE_CAN_INTTYPES @@ -578,7 +578,7 @@ char *ucstrstr(char *, const char *); #define mkssert(e) do { } while (/* CONSTCOND */ 0) #endif -#if (!defined(MKSH_BUILDMAKEFILE4BSD) && !defined(MKSH_BUILDSH)) || (MKSH_BUILD_R != 539) +#if (!defined(MKSH_BUILDMAKEFILE4BSD) && !defined(MKSH_BUILDSH)) || (MKSH_BUILD_R != 541) #error Must run Build.sh to compile this. extern void thiswillneverbedefinedIhope(void); int @@ -1350,7 +1350,7 @@ EXTERN mksh_ari_t x_lins E_INIT(24); /* Determine the location of the system (common) profile */ #ifndef MKSH_DEFAULT_PROFILEDIR -#define MKSH_DEFAULT_PROFILEDIR "/etc" +#define MKSH_DEFAULT_PROFILEDIR MKSH_UNIXROOT "/etc" #endif #define MKSH_SYSTEM_PROFILE MKSH_DEFAULT_PROFILEDIR "/profile" @@ -1748,8 +1748,6 @@ typedef struct XString { Area *areap; } XString; -typedef char *XStringP; - /* initialise expandable string */ #define XinitN(xs, length, area) do { \ (xs).len = (length); \ @@ -1825,6 +1823,15 @@ typedef struct { #define XPclose(x) aresize2((x).beg, XPsize(x), sizeof(void *), ATEMP) #define XPfree(x) afree((x).beg, ATEMP) +/* for print_columns */ + +struct columnise_opts { + struct shf *shf; + char linesep; + bool do_last; + bool prefcol; +}; + /* * Lexer internals */ @@ -2021,7 +2028,7 @@ void flushcom(bool); int search_access(const char *, int); const char *search_path(const char *, const char *, int, int *); void pr_menu(const char * const *); -void pr_list(char * const *); +void pr_list(struct columnise_opts *, char * const *); int herein(struct ioword *, char **); /* expr.c */ int evaluate(const char *, mksh_ari_t *, int, bool); @@ -2122,8 +2129,8 @@ void runtrap(Trap *, bool); void cleartraps(void); void restoresigs(void); void settrap(Trap *, const char *); -int block_pipe(void); -void restore_pipe(int); +bool block_pipe(void); +void restore_pipe(void); int setsig(Trap *, sig_t, int); void setexecsig(Trap *, int); #if HAVE_FLOCK || HAVE_LOCK_FCNTL @@ -2237,9 +2244,9 @@ void ksh_getopt_reset(Getopt *, int); int ksh_getopt(const char **, Getopt *, const char *); void print_value_quoted(struct shf *, const char *); char *quote_value(const char *); -void print_columns(struct shf *, unsigned int, +void print_columns(struct columnise_opts *, unsigned int, void (*)(char *, size_t, unsigned int, const void *), - const void *, size_t, size_t, bool); + const void *, size_t, size_t); void strip_nuls(char *, size_t) MKSH_A_BOUNDED(__string__, 1, 2); ssize_t blocking_read(int, char *, size_t) @@ -2420,13 +2427,26 @@ extern int tty_init_fd(void); /* initialise tty_fd, tty_devtty */ }) #define mksh_abspath(s) __extension__({ \ const char *mksh_abspath_s = (s); \ - (mksh_abspath_s[0] == '/' || (ksh_isalphx(mksh_abspath_s[0]) && \ + (mksh_cdirsep(mksh_abspath_s[0]) || \ + (ksh_isalphx(mksh_abspath_s[0]) && \ mksh_abspath_s[1] == ':')); \ }) +#define mksh_cdirsep(c) __extension__({ \ + char mksh_cdirsep_c = (c); \ + (mksh_cdirsep_c == '/' || mksh_cdirsep_c == '\\'); \ +}) +/* + * I've seen mksh_sdirsep(s) and mksh_vdirsep(s) but need to think + * more about the OS/2 port (and, possibly, toy with it) before I + * can merge this upstream, but good job so far @komh, thanks! + */ #else #define binopen2(path,flags) open((path), (flags) | O_BINARY) #define binopen3(path,flags,mode) open((path), (flags) | O_BINARY, (mode)) #define mksh_abspath(s) ((s)[0] == '/') +#define mksh_cdirsep(c) ((c) == '/') +#define mksh_sdirsep(s) strchr((s), '/') +#define mksh_vdirsep(s) vstrchr((s), '/') #endif /* be sure not to interfere with anyone else's idea about EXTERN */ diff --git a/var.c b/var.c index 0331d1e..64de0f9 100644 --- a/var.c +++ b/var.c @@ -28,7 +28,7 @@ #include #endif -__RCSID("$MirOS: src/bin/mksh/var.c,v 1.208 2016/10/22 23:56:50 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/var.c,v 1.209 2016/11/11 23:31:39 tg Exp $"); /*- * Variables @@ -133,7 +133,7 @@ initvar(void) struct tbl *tp; ktinit(APERM, &specials, - /* currently 15 specials: 75% of 32 = 2^5 */ + /* currently 18 specials: 75% of 32 = 2^5 */ 5); while (i < V_MAX - 1) { tp = ktenter(&specials, initvar_names[i], @@ -1149,6 +1149,13 @@ makenv(void) /* setstr can't fail here */ setstr(vp, val, KSH_RETURN_ERROR); } +#ifdef __OS2__ + /* these special variables are not exported */ + if (!strcmp(vp->name, "BEGINLIBPATH") || + !strcmp(vp->name, "ENDLIBPATH") || + !strcmp(vp->name, "LIBPATHSTRICT")) + continue; +#endif XPput(denv, vp->val.s); } if (l->flags & BF_STOPENV) @@ -1274,6 +1281,13 @@ setspec(struct tbl *vp) int st; switch ((st = special(vp->name))) { +#ifdef __OS2__ + case V_BEGINLIBPATH: + case V_ENDLIBPATH: + case V_LIBPATHSTRICT: + setextlibpath(vp->name, str_val(vp)); + return; +#endif #if HAVE_PERSISTENT_HISTORY case V_HISTFILE: sethistfile(str_val(vp)); @@ -1396,6 +1410,13 @@ unsetspec(struct tbl *vp) */ switch (special(vp->name)) { +#ifdef __OS2__ + case V_BEGINLIBPATH: + case V_ENDLIBPATH: + case V_LIBPATHSTRICT: + setextlibpath(vp->name, ""); + return; +#endif #if HAVE_PERSISTENT_HISTORY case V_HISTFILE: sethistfile(NULL); diff --git a/var_spec.h b/var_spec.h index 51cda3e..45fa0eb 100644 --- a/var_spec.h +++ b/var_spec.h @@ -19,7 +19,7 @@ */ #if defined(VARSPEC_DEFNS) -__RCSID("$MirOS: src/bin/mksh/var_spec.h,v 1.9 2016/07/25 21:02:13 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/var_spec.h,v 1.10 2016/11/11 23:31:39 tg Exp $"); #define FN(name) /* nothing */ #elif defined(VARSPEC_ENUMS) #define FN(name) V_##name, @@ -40,13 +40,22 @@ F0(NONE) /* 1 and up are special variables */ FN(BASHPID) +#ifdef __OS2__ +FN(BEGINLIBPATH) +#endif FN(COLUMNS) +#ifdef __OS2__ +FN(ENDLIBPATH) +#endif FN(EPOCHREALTIME) #if HAVE_PERSISTENT_HISTORY FN(HISTFILE) #endif FN(HISTSIZE) FN(IFS) +#ifdef __OS2__ +FN(LIBPATHSTRICT) +#endif FN(LINENO) FN(LINES) FN(OPTIND) From 0ba220d2c4a8eabdd8608d38a73ebc5365579841 Mon Sep 17 00:00:00 2001 From: tg Date: Fri, 11 Nov 2016 23:48:30 +0000 Subject: [PATCH 30/31] gcc 6.2 warnings (stupid uninitialised that wasn't, plus FALLTHROUGH fixes) --- edit.c | 10 +++++++--- funcs.c | 23 +++++++++++------------ main.c | 4 ++-- 3 files changed, 20 insertions(+), 17 deletions(-) diff --git a/edit.c b/edit.c index 163dfe0..4ed5ca3 100644 --- a/edit.c +++ b/edit.c @@ -28,7 +28,7 @@ #ifndef MKSH_NO_CMDLINE_EDITING -__RCSID("$MirOS: src/bin/mksh/edit.c,v 1.311 2016/11/11 23:31:33 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/edit.c,v 1.312 2016/11/11 23:48:28 tg Exp $"); /* * in later versions we might use libtermcap for this, but since external @@ -4165,6 +4165,8 @@ vi_cmd(int argcnt, const char *cmd) case 'Y': cmd = "y$"; /* ahhhhhh... */ + + /* FALLTHROUGH */ case 'c': case 'd': case 'y': @@ -4401,6 +4403,8 @@ vi_cmd(int argcnt, const char *cmd) if (hnum == hlast) hnum = -1; /* ahhh */ + + /* FALLTHROUGH */ case '/': c3 = 1; srchlen = 0; @@ -4539,6 +4543,7 @@ vi_cmd(int argcnt, const char *cmd) case CTRL('['): if (!Flag(FVIESCCOMPLETE)) return (-1); + /* FALLTHROUGH */ /* AT&T ksh */ case '\\': /* Nonstandard vi/ksh */ @@ -4611,8 +4616,7 @@ domove(int argcnt, const char *cmd, int sub) case 'T': fsavecmd = *cmd; fsavech = cmd[1]; - /* drop through */ - + /* FALLTHROUGH */ case ',': case ';': if (fsavecmd == ' ') diff --git a/funcs.c b/funcs.c index 2e5f44c..52366fd 100644 --- a/funcs.c +++ b/funcs.c @@ -38,7 +38,7 @@ #endif #endif -__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.318 2016/11/11 22:17:08 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.319 2016/11/11 23:48:29 tg Exp $"); #if HAVE_KILLPG /* @@ -284,8 +284,9 @@ c_print(const char **wp) const char *s; char *xp; XString xs; - XPtrV words; struct { + /* storage for columnisation */ + XPtrV words; /* temporary storage for a wide character */ mksh_ari_t wc; /* output file descriptor (if any) */ @@ -313,14 +314,12 @@ c_print(const char **wp) bool copipe; } po; + memset(&po, 0, sizeof(po)); po.fd = 1; po.ws = ' '; po.ls = '\n'; po.nl = true; po.exp = true; - po.col = false; - po.hist = false; - po.chars = false; if (wp[0][0] == 'e') { /* "echo" builtin */ @@ -455,7 +454,7 @@ c_print(const char **wp) if (*wp == NULL) return (0); - XPinit(words, 16); + XPinit(po.words, 16); } Xinit(xs, xp, 128, ATEMP); @@ -517,7 +516,7 @@ c_print(const char **wp) } if (po.col) { Xput(xs, xp, '\0'); - XPput(words, Xclose(xs, xp)); + XPput(po.words, Xclose(xs, xp)); Xinit(xs, xp, 128, ATEMP); } if (*wp != NULL) { @@ -526,17 +525,17 @@ c_print(const char **wp) goto print_read_arg; } if (po.col) { - size_t w = XPsize(words); + size_t w = XPsize(po.words); struct columnise_opts co; - XPput(words, NULL); + XPput(po.words, NULL); co.shf = shf_sopen(NULL, 128, SHF_WR | SHF_DYNAMIC, NULL); co.linesep = po.ls; co.prefcol = co.do_last = false; - pr_list(&co, (char **)XPptrv(words)); + pr_list(&co, (char **)XPptrv(po.words)); while (w--) - afree(XPptrv(words)[w], ATEMP); - XPfree(words); + afree(XPptrv(po.words)[w], ATEMP); + XPfree(po.words); w = co.shf->wp - co.shf->buf; XcheckN(xs, xp, w); memcpy(xp, co.shf->buf, w); diff --git a/main.c b/main.c index 1a983f1..ebbadd9 100644 --- a/main.c +++ b/main.c @@ -34,7 +34,7 @@ #include #endif -__RCSID("$MirOS: src/bin/mksh/main.c,v 1.321 2016/11/11 23:31:35 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/main.c,v 1.322 2016/11/11 23:48:30 tg Exp $"); extern char **environ; @@ -566,8 +566,8 @@ main_init(int argc, const char *argv[], Source **sp, struct block **lp) #endif if (!isuc(ccp)) ccp = null; - /* FALLTHROUGH */ #endif + /* FALLTHROUGH */ /* auto-detect from environment */ case 3: From 6d5496a81cdbda61242a98afdc8c23400b8191bc Mon Sep 17 00:00:00 2001 From: tg Date: Sat, 12 Nov 2016 00:20:37 +0000 Subject: [PATCH 31/31] make both cats --- Makefile | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index b1fd33a..a21d9a1 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -# $MirOS: src/bin/mksh/Makefile,v 1.154 2016/11/11 23:31:30 tg Exp $ +# $MirOS: src/bin/mksh/Makefile,v 1.155 2016/11/12 00:20:37 tg Exp $ #- # Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, # 2011, 2012, 2013, 2014, 2015, 2016 @@ -135,6 +135,13 @@ distribution: chown ${BINOWN}:${CONFGRP} ${DESTDIR}/etc/skel/.mkshrc chmod 0644 ${DESTDIR}/etc/skel/.mkshrc +.if make(cats) || make(clean) || make(cleandir) +MAN= lksh.1 mksh.1 +.endif +CLEANFILES+= ${MANALL:S/.cat/.ps/} ${MAN:S/$/.pdf/} ${MANALL:S/$/.gz/} +CLEANFILES+= ${MAN:S/$/.htm/} ${MAN:S/$/.htm.gz/} +CLEANFILES+= ${MAN:S/$/.txt/} ${MAN:S/$/.txt.gz/} + .include .ifmake cats @@ -145,16 +152,14 @@ V_GHOSTSCRIPT!= pkg_info -e 'ghostscript-*' . endif .endif -CLEANFILES+= ${MANALL:S/.cat/.ps/} ${MAN:S/$/.pdf/} ${MANALL:S/$/.gz/} -CLEANFILES+= ${MAN:S/$/.htm/} ${MAN:S/$/.htm.gz/} -CLEANFILES+= ${MAN:S/$/.txt/} ${MAN:S/$/.txt.gz/} -CATS_KW= mksh, ksh, sh +CATS_KW= mksh, lksh, ksh, sh, Korn Shell, Android +CATS_TITLE_lksh_1=lksh - Legacy Korn shell built on mksh CATS_TITLE_mksh_1=mksh - The MirBSD Korn Shell cats: ${MANALL} ${MANALL:S/.cat/.ps/} .if "${MANALL:Nlksh.cat1:Nmksh.cat1}" != "" . error Adjust here. .endif -.for _m _n in mksh 1 +.for _m _n in lksh 1 mksh 1 x=$$(ident ${SRCDIR:Q}/${_m}.${_n} | \ awk '/Mir''OS:/ { print $$4$$5; }' | \ tr -dc 0-9); (( $${#x} == 14 )) || exit 1; exec \