Merge commit '97ef0077f06cef6f6bb93b0dae22441078647486' as 'cde/programs/dtksh/ksh93'

This commit is contained in:
Jon Trulson
2022-08-27 13:53:17 -06:00
1152 changed files with 330758 additions and 0 deletions

View File

@@ -0,0 +1,870 @@
:
### this script contains archaic constructs that work with all sh variants ###
# Glenn Fowler
# AT&T Research
#
# @(#)C probe (AT&T Research) 2012-02-29
#
# probe [ -d ] c-compiler-path [ attributes ]
#
# common C probe preamble for the tool specific probes
#
# NOTE: some cc -E's do syntax analysis!
#
# probe_* are first eval'd and then attempted from left to right
#
probe_binding="-dy -dn -Bdynamic -Bstatic '-Wl,-ashared -Wl,+s' -Wl,-aarchive -call_shared -non_shared -dynamic -static -bshared -bstatic '' -static"
probe_env="CC_OPTIONS CCOPTS LD_OPTIONS LDOPTS LIBPATH LPATH"
probe_include="stdio.h iostream.h complex.h ctype.h plot.h stdarg.h varargs.h ranlib.h hash.h sys/types.h stab.h cmath cstdio iostream string"
probe_longlong="long 'long long'"
probe_longlong_t="__int64_t _int64_t __int64 _int64 int64"
probe_l="l yyreject m sin mopt sin"
probe_lxx="C exit ++ exit g++ exit"
probe_ppprefix="a n"
probe_size="size"
probe_src="cxx C cc c"
probe_sa=".sa"
probe_sd=".dll .lib .dll .x"
probe_sdb=".pdb"
probe_so=".dylib .so .sl"
probe_symprefix="_"
probe_verbose="'-v -v' '-# -#' '-d -d' -dryrun '-V -V'"
probe_version="--version -V -version -v"
#
# the following are set by the preamble for the tool specific probe
#
cc=cc
debug=
dir=.
dll=.dll
dynamic=
exe=exe
executable="test -x"
hosted=
ifs=${IFS-'
'}
obj=o
ppenv=
ppopt=
predef=
prepred=
sa=
sd=
sdb=
so=
sov=
static=
stdlib=
stdpp=
suffix_command=
if test "" != "$TMPDIR" -a -d "$TMPDIR"
then tmpdir=$TMPDIR
else tmpdir=/tmp
fi
tmpdir=$tmpdir/probe$$
undef="define defined elif else endif error if ifdef ifndef include line pragma undef __STDC__ __ARGC__ __BASE__ __BASE_FILE__ __DATE__ __FILE__ __FUNCTION__ __INCLUDE_LEVEL__ __LINE__ __PATH__ __TIME__ __TIMESTAMP__ __VERSION__"
version_flags=
version_stamp=
version_string=
#
# constrain the environment
#
DISPLAY=
LC_ALL=C
export DISPLAY LC_ALL
#
# now the common probes
#
while :
do case $1 in
-d) debug=1 ;;
-*) set ''; break ;;
*) break ;;
esac
shift
done
cc=$1
case $cc in
[\\/]*|[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz]:\\*)
;;
*) echo "Usage: $0 [ -d ] c-compiler-path [ attributes ]" >&2
exit 1
;;
esac
ATTRIBUTES=
eval $2
_probe_PATH=$PATH
PATH=/usr/bin:/bin:$PATH
case $0 in
*[\\/]*) dir=`echo $0 | sed -e 's,[\\/][\\/]*[^\\/]*\$,,'` ;;
esac
$executable . 2>/dev/null || executable='test -r'
case $SHELL in
[\\/]*|[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz]:\\*)
sh=$SHELL
;;
*) sh=/bin/sh
;;
esac
trap 'code=$?; cd ..; rm -rf $tmpdir; exit $code' 0 1 2 3
mkdir $tmpdir
cd $tmpdir
exec 3>&1 4>&2 </dev/null
case $debug in
"") exec >/dev/null 2>&1
(ulimit -c 0) >/dev/null 2>&1 && ulimit -c 0
;;
*) PS4='+$LINENO+ '
set -x
;;
esac
if (xxx=xxx; unset xxx)
then UNSET=1
else UNSET=
fi
eval set x $probe_env
while :
do shift
case $# in
0) break ;;
esac
eval x='$'$1
case $x in
'') continue ;;
esac
case $1 in
*PATH) _probe_export="$_probe_export $1='$x'" ;;
esac
case $UNSET in
'') eval $1=
export $1
;;
*) unset $1
;;
esac
done
if test -f "$dir/probe.ini"
then . "$dir/probe.ini"
IFS=$ifs
fi
mkdir suffix
cd suffix
for src in $probe_src
do echo "int main(){return 0;}" > ../test.$src
rm -f test*
if $cc -c ../test.$src
then set test.*
if test -f "$1"
then o="$*"
mv $* ..
for i in $o
do if $cc -o test.exe ../$i
then obj=`echo "$i" | sed -e 's,test.,,'`
$executable test.exe || executable="test -r"
set test*
rm *
if $cc -o test ../$i
then rm $*
set test.*
if $executable "$1"
then exe=`echo "$1" | sed -e 's,test.,,'`
suffix_command=.$exe
fi
fi
break 2
fi
done
fi
fi
done
cd ..
case $src in
c) ;;
*) echo '// (
int
main()
{
class { public: int i; } j;
j.i = 0;
int k = j.i + 1;
return k;
}' > dialect.$src
if $cc -c dialect.$src && $cc -o dialect.$exe dialect.$obj && $executable dialect.$exe
then mv dialect.$src dialect.c
rm -f dialect.$obj dialect.$exe
if $cc -c dialect.c && $cc -o dialect.$exe dialect.$obj && $executable dialect.$exe
then src=c
else set x $cc
while :
do shift
case $# in
0) break ;;
esac
case $1 in
*=*) continue ;;
esac
case `echo $1 | sed -e 's,.*/,,'` in
*CC*|*++*|*[xX][xX]*|*[pP][lL][uU][sS]*) ;;
*) src=c ;;
esac
break
done
fi
else src=c
fi
;;
esac
set x x '(' 1 'int x;' 0
while :
do shift
shift
case $# in
[01]) break ;;
esac
rm -f test.$obj
echo "$1" > test.$src
$cc -c test.$src
r=$?
case $r in
0) test -f test.$obj || r=1 ;;
*) r=1 ;;
esac
case $2:$r in
0:0) ;;
0:1) echo "$cc: not a C compiler: failed to compile \`\`$1''" >&4
exit 1
;;
1:0) echo "$cc: not a C compiler: successfully compiled \`\`$1''" >&4
exit 1
;;
esac
done
hosttype=`package CC="$cc" || $SHELL -c "package CC='$cc'"`
case $hosttype in
*[Uu][Ss][Aa][Gg][Ee]:*)
hosttype=`PATH=$_probe_PATH; export PATH; package CC="$cc" || $SHELL -c "package CC='$cc'"`
;;
esac
echo '#include <stdio.h>
int main(){printf("hello");return 0;}' > dynamic.$src
echo 'extern int sfclose() { return 0; }' > fun.$src
if $cc -c dynamic.$src && $cc -c fun.$src
then eval set x $probe_so
while :
do shift
case $# in
0) break ;;
esac
for i in foo junk
do rm -f dynamic.$exe
if $cc -L. -o dynamic.$exe dynamic.$obj -l$i
then : "there's really a -l$i"?
else rm -f dynamic.$exe
cat fun.$obj > lib$i$1
$cc -L. -o dynamic.$exe dynamic.$obj -l$i && $executable dynamic.$exe
x=$?
rm lib$i$1
case $x in
0) so=$1
rm -f dynamic.$exe > lib$i$1.1
$cc -L. -o dynamic.$exe dynamic.$obj -l$i && $executable dynamic.$exe
x=$?
rm lib$i$1.1
case $x in
0) sov=1 ;;
esac
break 2
;;
*) break
;;
esac
fi
done
k=
for i in "" .1 .2 .3 .4 .5 .6 .7 .8 .9
do rm -f dynamic.$exe > libc$1$i
$cc -L. -o dynamic.$exe dynamic.$obj && $executable dynamic.$exe
x=$?
(cd ..; rm $tmpdir/libc$1$i)
case $x in
0) ;;
*) k=X$k
case $k in
XXX) break ;;
esac
;;
esac
done
case $k in
XXX) so=$1
sov=1
break
;;
?*) so=$1
break
;;
esac
done
rm -f dynamic.$exe
if $cc -o dynamic.$exe dynamic.$obj 2>e && $executable dynamic.$exe
then e=`wc -l e`
maybe=
eval set x x $probe_binding
while :
do shift
shift
case $# in
0) break ;;
esac
rm -f dynamic.$exe
$cc -o dynamic.$exe $1 dynamic.$obj 2>e && $executable dynamic.$exe || continue
case $1 in
?*) case $maybe in
"") maybe=$1 ;;
*) maybe=-- ;;
esac
;;
esac
case `wc -l e` in
$e) ;;
*) continue ;;
esac
d=`ls -s dynamic.$exe`
rm -f dynamic.$exe
$cc -o dynamic.$exe $2 dynamic.$obj 2>e && $executable dynamic.$exe || continue
case `wc -l e` in
$e) ;;
*) continue ;;
esac
case `ls -s dynamic.$exe` in
$d) ;;
*) dynamic=$1
static=$2
maybe=
break
;;
esac
done
case $maybe in
""|--) ;;
*) rm -f dynamic.$exe
if $cc -o dynamic.$exe $maybe dynamic.$obj 2>e && $executable dynamic.$exe
then e=`wc -l e`
if $cc -o dynamic.$exe $maybe-bogus-bogus-bogus dynamic.$obj 2>e && $executable dynamic.$exe
then case `wc -l e` in
$e) ;;
*) dynamic=$maybe ;;
esac
else dynamic=$maybe
fi
fi
;;
esac
fi
fi
eval set x $probe_version
shift
for o in "$@"
do if $cc $o > version.out 2>&1
then version_string=`sed -e '/ is /d' -e 's/;/ /g' version.out | sed -e 1q`
case $version_string in
''|*[Ee][Rr][Rr][Oo][Rr]*|*[Ff][Aa][Tt][Aa][Ll]*|*[Ww][Aa][Rr][Nn][Ii][Nn][Gg]*|*[Oo][Pp][Tt][Ii][Oo][Nn]*)
;;
*) version_flags=$o
version_stamp=";VERSION;$o;$version_string;PATH;$cc"
break
;;
esac
fi
done
case $version_stamp in
'') eval set x $probe_version
shift
echo 'int main() { return 0; }' > version.i
for o in "$@"
do if $cc -c $o version.i > version.out 2>&1
then version_string=`sed -e '/ is /d' -e 's/;/ /g' version.out | sed -e 1q`
case $version_string in
''|*[Ee][Rr][Rr][Oo][Rr]*|*[Ff][Aa][Tt][Aa][Ll]*|*[Ww][Aa][Rr][Nn][Ii][Nn][Gg]*|*[Oo][Pp][Tt][Ii][Oo][Nn]*)
;;
*) version_flags=$o
break
;;
esac
fi
done
;;
esac
echo 'int main(){return 0;}' > hosted.$src
$cc -o hosted.$exe hosted.$src && ./hosted.$exe && hosted=1
echo '#!'$sh'
echo "" $@' > cpp
chmod +x cpp
case `./cpp -Dprobe` in
*-Dprobe*)
;;
*) cp /bin/echo cpp
chmod u+w cpp
;;
esac
for prefix in $probe_ppprefix `echo $cc | sed -e '/cc\$/!d' -e 's,cc\$,,' -e 's,.*/,,'`
do cp cpp ${prefix}cpp
done
echo "" > flags.$src
echo '#pragma pp:version' > libpp.$src
if test `realcppC=./cpp $cc -Dprobe -E flags.$src | tee cpp.out | grep -c '[-]Dprobe'` -eq 1
then ppenv='realcppC=${ppcmd}'
elif test `cppC=./cpp $cc -Dprobe -E flags.$src | tee cpp.out | grep -c '[-]Dprobe'` -eq 1
then ppenv='cppC=${ppcmd}'
elif test `_CPPNAME=./cpp $cc -Dprobe -E flags.$src | tee cpp.out | grep -c '[-]Dprobe'` -eq 1
then ppenv='_CPPNAME=${ppcmd}'
elif test `_CPP=./cpp $cc -Dprobe -E flags.$src | tee cpp.out | grep -c '[-]Dprobe'` -eq 1
then ppenv='_CPP=${ppcmd}'
elif test `$cc -Dprobe -E -%p+. flags.$src | tee cpp.out | grep -c '[-]Dprobe'` -eq 1 && test `$cc -Dprobe -E -%p+. flags.$src | wc -l` -eq 1
then ppopt='-%p+${ppdir}'
elif test `$cc -Dprobe -E -Yp,. flags.$src | tee cpp.out | grep -c '[-]Dprobe'` -eq 1
then ppopt='-Yp,${ppdir}'
elif test `$cc -Dprobe -E -Qpath $tmpdir flags.$src | tee cpp.out | grep -c '[-]Dprobe'` -eq 1
then ppopt='-Qpath ${ppdir}'
elif test `$cc -Dprobe -E -tp -B./ flags.$src 2>err.out | tee cpp.out | grep -c '[-]Dprobe'` -eq 1 -a ! -s err.out
then ppopt='-tp -B${ppdir}/'
elif test `$cc -Dprobe -E -B./ flags.$src | tee cpp.out | grep -c '[-]Dprobe'` -eq 1
then ppopt='-B${ppdir}/'
elif test `$cc -Dprobe -E -tp -h./ -B flags.$src | tee cpp.out | grep -c '[-]Dprobe'` -eq 1
then ppopt='-tp -h${ppdir}/ -B'
elif test `$cc -Dprobe -E -t p,./cpp flags.$src | tee cpp.out | grep -c '[-]Dprobe'` -eq 1
then ppopt='-t p,${ppcmd}'
else {
eval set x $probe_verbose
shift
for o in "$@"
do $cc -E $o flags.$src
done
} 2>&1 | sed -e "s/['\"]//g" > cpp.out
fi
set x `sed -e 's,[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz]:\\\\,/,g' -e 's,\\\\,/,g' cpp.out`
def=
definclude="-I+C -I-H"
stdinclude=$definclude
case $hosted in
"") usrinclude= ;;
esac
cmdinclude=
while :
do case $# in
0|1) break ;;
esac
shift
case $1 in
-A) case $2 in
*\(*\)) shift
prepred="$prepred `echo $1 | sed 's/\(.*\)(\(.*\))/\1 \2/'`"
;;
esac
;;
-A\(*\))
prepred="$prepred `echo $1 | sed 's/-A\(.*\)(\(.*\))/\1 \2/'`"
;;
-[DI][-+][ABCDEFGHIJKLMNOPQRSTUVWXYZ]*)
stdpp=1
case $1 in
-I?[CH]) case $def in
?*) definclude="$definclude $1" ;;
*) stdinclude="$stdinclude $1" ;;
esac
;;
-I-S*|-YI,*) usrinclude="`echo $1 | sed 's/....//'`" ;;
-Y?,*) ;;
-Y*) usrinclude="`echo $1 | sed 's/..//'`" ;;
esac
;;
-D) shift
case $1 in
[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_]*=*)
predef="$predef
`echo $1 | sed -e 's/=.*//'`"
;;
[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_]*)
predef="$predef
$1"
;;
esac
;;
-Dprobe);;
-D*) case $1 in
-D[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_]*=*)
predef="$predef
`echo $1 | sed -e 's/^-D//' -e 's/=.*//'`"
;;
-D[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_]*)
predef="$predef
`echo $1 | sed -e 's/^-D//'`"
;;
esac
;;
-I) shift
case $1 in
/*) case $def in
?*) definclude="$definclude $1" ;;
*) stdinclude="$stdinclude $1" ;;
esac
cmdinclude="$cmdinclude $1"
;;
esac
;;
-I/*) f=`echo X$1 | sed 's/X-I//'`
case $def in
?*) definclude="$definclude $f" ;;
*) stdinclude="$stdinclude $f" ;;
esac
cmdinclude="$cmdinclude $f"
;;
-U) shift
undef="$undef $1"
;;
-U*) undef="$undef `echo $1 | sed 's/^-U//'`"
;;
flags.$src)def=
;;
esac
done
stdinclude="$stdinclude $definclude"
case " $stdinclude " in
*\ $usrinclude\ *)
case $usrinclude in
/usr/include)
usrinclude=
;;
*) case " $stdinclude " in
*\ /usr/include\ *)
usrinclude=
;;
*) usrinclude=/usr/include
;;
esac
;;
esac
;;
esac
tstinclude=`$cc -v -E flags.$src 2>&1 | sed -e '1,/[iI][nN][cC][lL][uU][dD][eE][ ]*<[.][.][.]>/d' -e '/^[eE][nN][dD] [oO][fF] [sS][eE][aA][rR][cC][hH]/,\$d'`
j=$tstinclude
case $j in
*/*) ;;
*) j=$cmdinclude ;;
esac
tstinclude=
good=
nogood=
c_hdr="stdio.h ctype.h"
C_hdr="libc.h"
for i in $j
do if test -d "$i"
then tstinclude="$tstinclude $i"
h=
for f in $c_hdr
do if test -f "$i/$f"
then case $i in
*/CC) nogood=1 ;;
*) good=1 ;;
esac
else h="$h $f"
fi
done
c_hdr=$h
h=
for f in $C_hdr
do if test -f "$i/$f"
then case $i in
*/CC) nogood=1 ;;
*) good=1 ;;
esac
else h="$h $f"
fi
done
C_hdr=$h
fi
done
case $nogood in
1) good=0 ;;
esac
case $good in
1) case $c_hdr in
?*) bad=1
usrinclude=/usr/include
set '' $tstinclude /usr/include
;;
*) set '' $tstinclude
;;
esac
shift
stdinclude=$*
echo "#include <sys/types.h>" > include.$src
$cc -E include.$src | sed -e '/# 1 "[\\/]/!d' -e 's,[^"]*",,' -e 's,[\\/][^\\/]*".*,,' -e 's,[\\/]sys,,' > include.out
for f in `cat include.out`
do if test -d "$f"
then g=`echo $f | sed -e 's,[\\/][\\/]*[^\\/]*$,,'`
case " $stdinclude " in
*\ $f\ *|*\ $g\ *)
;;
*) stdinclude="$stdinclude $f"
case $f in
/usr/include) usrinclude=$f ;;
esac
bad=1
;;
esac
fi
done
;;
*) case $ppopt$ppenv in
?*) echo '#!'$sh'
echo $VIRTUAL_ROOT | sed "s/:.*//"' > cpp
chmod +x cpp
ppcmd=cpp
ppdir=.
eval x='`'$ppenv '$'cc -E $ppopt flags.$src'`'
case $x in
?*) tstinclude=$x/usr/include
;;
esac
cp /bin/echo cpp
chmod u+w cpp
;;
esac
eval set x $probe_include
while :
do shift
case $# in
0) break ;;
esac
echo "#include <$1>" > include.$src
$cc -E include.$src
done > include.out
ccinclude=
x=$stdinclude
stdinclude=
subinclude=
for f in $x $tstinclude `sed -e 's,\\\\,/,g' -e 's,///*,/,g' -e 's,"[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz]:/,"/,g' -e '/^#[line ]*[0123456789][0123456789]*[ ][ ]*"[\\/]/!d' -e 's/^#[line ]*[0123456789][0123456789]*[ ][ ]*"\(.*\)[\\/].*".*/\1/' include.out | sort -u`
do case $f in
-*) ;;
*/) f=`echo $f | sed -e 's,//*\$,,'` ;;
*/.) f=`echo $f | sed -e 's,//*.\$,,'` ;;
esac
case $f in
-I*) ;;
*/cc) ccinclude=1
;;
*/sys) continue
;;
*/include/*/*)
;;
*/include/*)
subinclude="$subinclude $f"
continue
;;
esac
if test -d "$f"
then case " $stdinclude " in
*\ $f\ *) ;;
*) stdinclude="$stdinclude $f" ;;
esac
fi
done
rm include.out
case $ccinclude in
?*) eval set x $probe_include
while :
do shift
case $# in
0) break ;;
esac
echo "#include <cc/$1>" > include.$src
if $cc -E include.$src > /dev/null
then break
fi
done
case $# in
0) ;;
*) x=$stdinclude
stdinclude=
for f in $x
do case $f in
*/cc) ;;
*) stdinclude="$stdinclude $f" ;;
esac
done
;;
esac
;;
esac
case $subinclude in
?*) for i in $subinclude
do for j in $stdinclude
do case $i in
$j/*/*) ;;
$j/*) both=
eval set x $probe_include
while :
do shift
case $# in
0) for k in $both
do echo "#include <$k>" > include.$src
$cc -E include.$src > include.out
I=`grep -c $i/$k < include.out`
J=`grep -c $j/$k < include.out`
case $I:$J in
0:*) ;;
*:0) stdinclude="$i $stdinclude"
break
;;
esac
done
continue 3
;;
esac
if test -f $i/$1
then if test ! -f $j/$1
then break 2
fi
both="$both $1"
fi
done
;;
$j) continue 2
;;
esac
done
stdinclude="$i $stdinclude"
done
;;
esac
{
for i in $stdinclude
do
case $i in
$usrinclude) ;;
*) echo $i $i ;;
esac
done
eval set x $probe_include
while :
do shift
case $# in
0) break ;;
esac
echo "#include <$1>" > t.c
p=
for j in `$cc -E t.c | grep "$1" | sed -e 's,\\\\,/,g' -e 's,"[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz]:/,"/,g' -e '/^#[line ]*1[ ][ ]*"[\\/]/!d' -e 's/^#[line ]*1[ ][ ]*"\(.*\)[\\/].*".*/\1/'`
do j=`echo $j | sed -e 's,///*,/,g' -e 's,/$,,'`
case $p in
?*) echo $p $j ;;
esac
p=$j
done
done
case $usrinclude in
?*) echo $usrinclude $usrinclude ;;
esac
} | tsort > tmp.tmp
tstinclude=`cat tmp.tmp`
bad=
for i in $stdinclude
do case "
$tstinclude
" in
*"
$i
"*) ;;
*) bad=1
break
;;
esac
done
;;
esac
case $bad in
"") x=$stdinclude
stdinclude=
z=
for i in $tstinclude
do case " $x " in
*" $i "*)
stdinclude="$stdinclude $i"
z=$i
;;
esac
done
case $usrinclude in
'') usrinclude=$z ;;
esac
;;
esac
case $hosted in
"") case $usrinclude in
/usr/include) usrinclude= ;;
esac
;;
esac
case $usrinclude in
?*) case " $stdinclude " in
*\ $usrinclude\ *)
x=$stdinclude
stdinclude=
for f in $x
do case $f in
$usrinclude) ;;
*) stdinclude="$stdinclude $f" ;;
esac
done
;;
esac
;;
esac
# drop dups -- they creep in somehow
x=$stdinclude
stdinclude=
for f in $x
do case " $stdinclude $usrinclude " in
*" $f "*) ;;
*) stdinclude="$stdinclude $f" ;;
esac
done

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,170 @@
## mamake and the MAM language ##
MAM (Make Abstract Machine) is a simple rule-based make language
that is implemented in just six four-letter commands and five attributes,
yet allows unlimited flexibility as it can execute arbitrary shell code.
The program implementing MAM, `mamake`,
is a portable C90 program written in a single file, `mamake.c`.
This allows ksh 93u+m,
or other programs using this build system,
to be built using only a standard C compiler and utilities installation
without any other dependencies or complications.
MAM was designed by Glenn Fowler at AT&T.
The [original documentation](http://web.archive.org/web/20041227143022/http://www2.research.att.com/~gsf/mam/mam.html)
for MAM specified a more extensive language than was actually implemented in `mamake.c`,
while the `ignore` attribute is not documented there.
This file documents the MAM implementation that we are actually using.
`mamake` processes make files called `Mamfile`.
These were originally generated by a complex AT&T make system called `nmake`.
The intention was for `mamake` to process generated Mamfiles only
and not for it to replace `make`.
Yet, we are using it as our `make` in the ksh 93u+m distribution.
`nmake` was slow, brittle, and did not work on some modern systems, e.g. macOS.
It was not worth fixing because it is about as complex as ksh itself --
whereas `mamake` is simple and portable, and offers all the same flexibility.
Compared to the 2012-08-01 AT&T distribution,
ksh 93u+m made a few minor changes to `mamake` that make it easier to maintain Mamfiles by hand:
* All Mamfiles have been indented for legibility. (See `bin/Mamfile_indent` in the distribution.)
* Indentation and word separators may use any whitespace (e.g. tabs), not only spaces.
* Unrecognized commands and rule attributes throw an error instead of being silently ignored.
* Fixed some crashing bugs and memory leaks.
## Commands ##
MAM commands have the following basic form:
*command* [ *argument* [ *operand string* ] ]
The *command* name consists of four lower-case letters.
Unrecognized commands or attributes are an error.
The *argument* is a single word.
The *operand string* is any arbitrary text until the end of the line.
### Comments ###
`note` is the comment command and is ignored.
For historical reasons, `info` and `meta` are also ignored.
### Rules ###
`make` *rule* [ *attribute* ... ]
`done` *rule* [ *attribute* ... ]
A `make`...`done` block defines the target rule named *rule* using the other commands described here.
Unless the `virtual` attribute is used, *rule* names the pathname of the file generated or referenced by the rule.
Dependencies may be defined in two ways:
1. By nesting `make`...`done` blocks:
the enclosing *rule* is the parent
and the enclosed *rule*s are the prerequisites.
2. By using the `prev` command (see **Referencing previously defined rules** below)
to reference a previous `make`...`done` block.
The dependency is defined as if that block were repeated at the `prev` command's location.
If the block contains one or more `exec` commands (see **Shell actions** below),
the `done` command executes the shell script defined by them.
One or more of the following *attribute*s may be specified
by appending them to the `make` or `done` command:
* `archive`: Ignored.
Historically used to mark the generation of an `ar`(1) archive.
* `dontcare`: Marks files that do not need to exist.
If the file exists then its last-modified timestamp is checked and propagated,
otherwise it is silently ignored.
* `generated`: Marks rules that produce output files generated by a shell action.
The `exec` command implicitly assigns this attribute, but it is customary to specify it regardless.
* `ignore`: The timestamp associated with *rule* is ignored in dependency resolution.
* `implicit`: Marks the current rule as an implicit prerequisite of the enclosing parent rule.
An implicit prerequisite can make the parent rule out of date without triggering the parent action.
Implicit prerequisites usually correspond to `#include` prerequisites.
For example, if `foo.o` is generated from `foo.c` and `foo.c` includes `foo.h`,
then `foo.h` should be marked as an implicit prerequisite of `foo.c`
so that touching `foo.h` does not make `foo.c` out of date while making `foo.o` out of date.
* `joint`: Ignored.
Historically used to mark one of a group of rules that are built by a single shell action.
* `virtual`: Marks a rule that is not associated with any file.
The commands within are executed every time the Mamfile is processed.
By convention, a virtual rule named `all` makes everything,
and a virtual rule named `install` performs installation.
### Referencing previously defined rules ###
`prev` *rule* [ *attribute* ... ]
This command references a rule that has previously been defined by `make`...`done`,
regardless of block nesting level.
It can be used to make a rule a prerequisite of multiple `make`...`done` blocks without repeating the rule.
By convention, the *attribute*s of the referenced block are repeated in the `prev` command.
However, `mamake` ignores anything after *rule*.
### MAM variables ###
`setv` *variable* [ *defaultvalue* ]
Defines a new MAM *variable*, optionally assigning the initial *defaultvalue*.
If the *defaultvalue* begins and ends with double quotes (`"`), those are discarded.
If the variable already has a value, the `setv` command is ignored; assigning a new value is not possible.
When `mamake` starts, it imports all environment variables as MAM variables,
so any variable's default value can be overridden by exporting an environment variable by its name.
MAM variables are referenced using the sh-style `${`...`}` syntax, though the braces are *not* optional.
Any reference to an undefined variable is silently left unexpanded (and not replaced by the empty string).
Expansion of MAM variable references is recursive, i.e., the value may itself contain other variable references.
Beware: there is no reference loop detection.
[`TODO`: figure out and document advanced expansion syntax supported by `substitute()` in `mamake.c`]
### Shell actions ###
`exec` `-` *code*
One or more `exec` commands within a `make`...`done` block
define a shell script that is executed for *rule*.
The word following `exec` is ignored; by convention it is `-`.
Each `exec` command appends a line of code to the shell script for the current rule.
It is customary for a rule's `exec` commands to be contiguous, but not necessary.
Before adding each line of code to the script,
MAM variable references (see **MAM variables** above)
are expanded; their literal values are inserted into the *code* line
(beware: no quoting is applied!).
When `mamake` encounters the `done` command,
the script is executed by the shell whose path is in the `SHELL` environment variable
or, absent that, by `/bin/sh`.
The `exec` command assigns the `generated` attribute to the current rule, even if it was not specified.
### Binding libraries ###
`bind` `-l`*libraryname* [ `dontcare` ]
An argument of `-l`*libraryname* (or `+l`*libraryname*)
causes a MAM variable `mam_lib`*libraryname* to be defined (see **MAM variables** above).
The variable will contain either the compiler argument for linking to the library *libraryname*
(either the `-l`*libraryname* flag, or the full path in case of a static library)
or, if the `dontcare` attribute is specified, possibly the empty string.
This can be used both for AST libraries shipped with the distribution and for system libraries.
If the library file is found in the distribution,
its time stamp is checked and the current target is marked as outdated if it is newer.
There is also a mechanism to communicate library dependency information across Mamfiles and `mamake` invocations.
If a file named *libraryname* in the current directory
or an `${INSTALLROOT}/lib/lib/`*libraryname*`.req` file
exists, `mamake` processes each of the words in the form `-l`*libraryname* in its contents
as if they were arguments to `bind` commands
and the resulting values are appended to the value of `mam_lib`*libraryname*
as dependencies separated by spaces.
`mamake` does not create these dependency files;
they are expected to be generated by Mamfile shell actions (see **Shell actions** above).
If no such dependency file exists, and the `dontcare` attribute is added,
then `mamake` compiles a small test program on the fly to check if the library exists;
if this fails, the `mam_lib`*libraryname* variable will be emptied.
Any `bind` command whose argument does not start with `-l` or `+l` is ignored.
[`TODO`: `bind` is not yet fully understood; more `mamake.c` code analysis is required.
In `require()` in `mamake.c` there is some special handling for dynamic libraries.
Note that the `bind` functionality implemented in `mamake.c`
is completely different from that described in the original documentation.]

View File

@@ -0,0 +1,938 @@
This file is of historical interest only. For recent changes in both ksh 93u+m
and the accompanying libraries, see the file NEWS in the top-level directory.
____
12-07-17 iffe.sh: add C code NOTE("...") to amend --verbose output
12-06-26 iffe.sh: fix "npt foo" to handle function-like macro foo()
12-06-20 package.sh: use $KSH for rt in "results test"
12-06-15 Makefile: add PLUGIN_LIB to $INSTALLROOT/bin/.paths and BUILTIN_LIB => PLUGIN_LIB
12-06-15 package.sh: add PLUGIN_LIB to $INSTALLROOT/bin/.paths and BUILTIN_LIB => PLUGIN_LIB
12-06-13 package.sh: handle admin.db column output
12-06-08 iffe.sh: fix 12-06-06 typo
12-06-06 iffe.sh: check for -l* in reverse and accumulative order (e.g., for -last & -lm)
12-06-04 package.sh: always check $INSTALLROOT/lib/package/profile
12-05-31 Makefile: ID=ast; $(INSTALLROOT)/prototyped.h => $(INSTALLROOT)/$(ID)/prototyped.h
12-05-28 iffe.sh: API foo YYYYMMDD => FOOAPI(rel) test macro
12-05-24 package.sh: change admin.db comment => owner attributes
12-04-25 ratz.c: add sear -k option to keep installation tmp dir on exit
12-04-17 package.sh: skip sh version logic for ``use''
12-04-17 cc.ibm.risc*: _LARGEFILE64_SOURCE => _LARGE_FILE_API moved to libast/features
12-04-09 cc.ibm.risc*: speak aixese for _LARGEFILE64_SOURCE
12-02-29 cc.darwin.i386*: handle default cc vs kernel bittedness
12-02-29 C+probe: add __TIMESTAMP__ to the nopredefined list
12-02-29 package.sh: don't assume grep -q or /usr/local/lib in LD_LIBRARY_PATH
12-02-29 package.sh: fix ksh vs -lcmd compatibility checks
12-02-23 iffe.sh: checkcc() before checkread() for sensible diagnostics
12-02-14 package.mk: { --clobber --compare --link=lib*.a* } for --mam=static
12-02-14 package.mk: export LICENSEFILEDEFAULT instead of LICENSEFILE
12-02-14 package.sh: handle @(cc|ld).${HOSTTYPE}* intercepts
12-02-07 package.sh: add { clean clobber } actions
12-02-02 regress.sh: fix ulimit -c defaults for --nokeep
12-01-18 regress.sh: add INPUT|OUTPUT|ERROR -e 'filter' to filter before comparison
12-01-21 package.sh: fix `admin make' bug that created unused $INSTALLROOT/lib
12-01-21 Makefile: :PACKAGE: license=ast -- oops
12-01-20 cc.darwin,cc.mvs.390: tmp=/tmp/cc.${USER:-$LOGNAME}.$$.err
12-01-12 package.sh: add admin make share closure to handle alternate HOSTTYPEs
11-12-13 iffe.sh: add /*<NOSTDIO>*/ test code comment to disable default #include <stdio.h>
11-11-11 C+probe: test for .so before .sl
11-10-26 package.sh: don't forget about *.pkg for admin update
11-10-18 cc.*-icc: update and add more
11-10-11 package.sh: handle package make|view when no source installed
11-09-11 package.sh: count admin '*** termination code' errors
11-08-31 mamake.c: add -e, ignore use recursive prereq timestamps
11-08-29 iffe.sh: add ``set stdio try1.h - try2.h ...''
11-08-29 iffe.sh: trap EXIT => trap 0 for ancient sh
11-08-11 iffe.sh: handle ancient sort that doesn't have -k
11-06-01 make.probe: add more /lib64 logic
11-05-01 package.sh: fix admin ditto to sync LICENSES too
11-03-25 package.sh: initialize { $SED $TR } before first use!
11-03-21 package.sh: fix vpath probes
11-03-17 iffe.sh: fix cleanup to rm $tmp* instead of $tmp*.*
11-02-24 package.sh: change curl usage to "curl -L ..."
11-02-11 package.sh,C+probe,make.probe,mamprobe.sh: add ###.*archaic.*###
11-02-02 Makefile: add :MAPLIB: check for ancient -lw
11-02-02 make.probe: handle -print-multi-directory => 64 => /usr/lib64 /lib64
11-02-02 package.sh: HOSTTYPE=*,*cc*[,-*,...] sets CC [ and CCFLAGS ]
11-02-02 make.probe: handle gcc $ORIGIN link but exec failure -- gee thanks
11-01-25 cc.hp.ia64: bundled cc is a pile of shaving cream
11-01-07 iffe.sh: check debug==3 for is_hdr() failure
10-11-22 ditto.sh: fix timing problem between |& and exec &p
10-11-10 package.sh: fix cc cross compile check to use checkcc absolute path
10-10-10 package.sh: list main env vars at start of make action
10-10-10 ratz.c: tweak windows delays
10-09-10 ratz.c: add _SEAR_ARGS for _SEAR_EXEC
10-09-01 package.sh: fix ratz from source logic
10-08-25 package.mk: consolidate license file search in .package.licenses.
10-08-22 ratz.c: run sear bootstrap command detached
10-08-20 C+probe: version_stamp only if version_flags works
10-08-17 package.sh: unset makerules *DIR variables in env
10-08-15 package.sh: "make" action now lists some env values
10-08-11 mktest.sh: add "DO command ..."
10-07-27 rt.sh: handle "rt X=Y ..."
10-06-29 ratz.c: non-option sear args passed to sear_exec()
10-06-25 iffe.sh: "api" op changed to not do "map-libc" type mappings
10-06-25 package.sh: "force admin ditto" => no ditto --update option
10-06-22 C+probe: handle cc that require .[ci] input for version info
10-06-21 ditto.sh: change default remote access to ssh (about time)
10-06-12 regress.sh: DIAGNOSTICS [ 1 | 0 | pattern ] and fix EXIT for all
10-06-09 package.sh: add AT&T to usable nmake check
10-06-06 iffe.sh,iffe.tst: add { api ver } ops
10-04-22 package.sh: update "html binary|source" NAME/PASSWORD info
10-04-15 iffe.sh: don't forget candidate headers for hdr|sys!
10-04-11 WWW.mk: disable man page metarule -- now done by admin-man(1)
10-02-14 package.sh: $CC verification needs $INSTALLROOT/bin in PATH
10-02-11 package.sh: fix package admin make report error count
10-02-02 package.sh: fix write binary bug that did scp on local fs
10-02-02 package.mk: up to date binary targets must still be in PACKAGE.*.lst
10-01-01 package.sh: fix premature $INSTALLROOT/bin during cross compile check
10-01-01 make.probe: handle ['"] in CC.VERSION.STRING
09-12-04 iffe.sh: add "opt name" to check for name in $PACKAGE_OPTIONS
09-11-30 mktest.sh: change RESET to STATE.RESET to make it global
09-11-14 make.probe: use gcc { -print-multi-directory -print-search-dirs }
09-11-11 package.sh: re-order and combine cc checks
09-10-27 C+probe,make.probe,probe.win32: add CC.SUFFIX.DEBUG
09-10-21 iffe.sh,Makefile: test -e is not in ksh88!
09-10-06 iffe.sh: handle cc -E #error with 0 exit status (sgi)
09-10-06 package.sh: stub in ar intercept checks -- not used yet
09-10-06 ar.ibm.risc: add ar intercept because some AIX require -Xfoo first!!
09-09-24 regress.sh: fix UMASK logic to create test support files before umask
09-08-28 release.c: change docs to mention stdin if no file operands
09-08-24 package.sh: fix isascii() bug that failed on od(1) trailing space
09-08-20 make.probe: add CC.SHARED.NAME
09-08-20 regress.sh: add { JOB CONTINUE EXITED KILL FIFO }
09-08-11 package.sh: filter lines containing : for package results
09-07-31 make.probe: add CC.AR.ARFLAGS (for AIX ar -xany)
09-07-31 package.sh,cc.*: fix -dumpmachine to handle 32/64/* bit options
09-06-24 package.sh: fix admin.db output formatting
09-05-05 package.sh: export dll hackery environment vars
09-05-05 package.sh: handle non-identifier hostnames
09-05-05 mamake.c: pass undefined ${...} identifiers to the shell
09-05-05 mamake.rt: add macro expansion regression tests
09-05-01 iffe.sh: fix output initialization *again*
09-04-28 package.sh: handle admin.db contact field $9
09-04-15 iffe.sh: add implicit "ini" op to initialize io for subsequent ops
09-03-31 regress.sh: EXPORT before test => global ENVIRON[]
09-03-26 package.sh: test fail pattern is 'fail[es]'
09-03-26 UNIT - ... appends (options) to command line
09-03-19 TEST.mk: x.tst => x only if x is command target
09-03-15 regress.sh: add ${MAIN} for base name of main unit
09-03-10 TEST.mk: add .SOURCE:tests if tests is a dir
09-03-03 regress.sh: allow command line unit to override UNIT
09-03-03 mktest.sh: handle IO == $'\n'
09-02-02 package.sh: delay $INSTALLROOT/bin/.paths generation until mamprobe runs
09-01-30 cc.mvs.390: c89 balks at [ ()] in -Dname="..."!
09-01-27 package.sh: add isascii() to use ratz instead of tar
09-01-20 hurl.sh: add --size=bytes option
09-01-08 TEST.mk: add test.* prereqs, multiple arg lists with :T=*: binding
09-01-03 regress.sh: fix UNIT to allow command line override
09-01-03 mktest.sh: handle TWD
08-12-24 package.sh: fix cross-compile HOSTTYPE logic
08-12-15 package.sh,hurl.sh: handle http codes { 301 302 303 }
08-10-16 make.probe '-fno-stack-protector -fno-stack-protector-all' to cop out!!
08-09-30 rt.sh: fix ksh93 regression test signal count
08-09-26 regress.sh: ignore SIGPIPE for SET pipe-input
08-09-24 package.sh: package only test foo => make --recurse=only recurse tests foo
08-09-20 make.probe: handle another /usr/bin/file shared lib description
08-09-20 regress.sh: add --pipefail for SET pipe-input ...
08-09-17 Makefile: add gdbm1.c for <gdbm-ndbm.h>
08-09-10 make.probe: add CC.NOPROTECT
08-08-08 mktest.sh: add --width=width
08-08-05 dbm.req: favor sleepycat ndbm compatibility
08-08-04 C+probe: fix stdlib initialization logic
08-06-24 package.sh: fix $INSTALLROOT/bin/cc intercept time stamp file typo
08-06-20 TEST.mk: make the localyunit before *.rt => *.tst -- doh
08-06-20 mktest.sh: prepend $PWD onto PATH for local units -- doh^2
08-06-11 regress.sh: fix bug that skipped the last test
08-05-20 regress.sh: add --local to put *.tmp dir in local fs
08-05-05 regress.sh: add IF command ... ELIF command ... ELSE ... FI
08-05-01 package.sh: package test => ulimit -c 0
08-04-28 regress.sh: fix EXPORT quoting
08-04-28 regress.sh: fix UNIT set check args too
08-04-24 rt.sh: exit code > 256 => signal termination
08-04-10 C+probe: change probe_so order to check .so last (Mac OS X ld workaround)
08-04-01 package.sh: handle multiple admin HOSTTYPEs per HOST
08-03-28 C+probe: add C++ #include <iostream> (no extension) dir probes
08-03-17 regress.sh: fix trap on EXIT, add terminated note to final tally
08-02-28 make.probe: fix probe_warn to include ld!
08-02-02 make.probe: add CC.RUNPATH to match default -L order
08-01-31 package.sh: check lib64 for LD_LIBRARY_PATH
08-01-31 iffe.sh: tweak ancient /bin/sh workarounds
08-01-28 make.probe: Darwin ld export dynamic is -force_flat_namespace
08-01-28 C+probe: handle SGI cc error message but exit 0 botch(es)
08-01-23 package.sh: fix checksum doc typo
08-01-09 C+probe: add __FUNCTION__ to the undef (don't check) list
07-12-14 iffe.sh: add set nooptimize
07-12-03 package.sh: add LC_ALL=C
07-11-27 package.sh: fix overaggressive *.md5 cleanup
07-11-20 iffe.sh: treat exit status >= 250 as normal error with no signal
07-11-05 package.sh: fix write op error count pattern
07-11-05 package.mk: fix $(~req) .ver binding
07-08-11 probe.win32: add cl.exe setuid workaround, CC.VERSION[.STRING]
07-08-01 package.sh: handle 'package read lcl|tgz'
07-05-08 regress.sh: execute basename instead of absolute path for short $0
07-04-27 cc.sgi.mips[34]: for #error to exit non-zero -- a no brainer
07-04-20 mktest.sh: defer to systems without 'grep -q' -- sigh
07-04-11 mamprobe.sh: handle $(CC.*) => ${mam_cc_*}, $(...) => ${...}
07-04-11 make.probe: fix CC.PICBIG probe, default { CC.PIC CC.DLL } to BIG
07-04-04 iffe.sh: prepend ${tst}${ext} to each .c probe
07-03-28 package.sh: fix binary tgz architecture type duplication
07-03-28 package.mk: add binary write PACKAGE.$HOSTTYPE.lst
07-03-28 iffe.sh: add -F header to mac test
07-03-23 make.probe: handle file(1) that returns 'archive' for .so
07-03-22 mamprobe.sh: fix STDED probe for implementations that ignore EOF
07-03-11 package.sh: add nocopyright and tst => nocopyright
07-03-11 package.mk: add copyright=0
07-03-08 C+probe: restore IFS after probe.ini
07-02-26 mamake.c: expand first of ${mam_lib*} for ${AR}
07-01-05 package.sh: fix "admin write binary" logic
07-01-01 iffe.sh: add "cmd" --verbose trace
07-01-01 iffe.sh: sort => LC_ALL=C sort
07-01-01 C+probe: LC_ALL=C
06-12-22 make.probe: lean on gcc -v for stdlib, but preserve /usr/local!
06-11-23 package.sh: *.md5 are not tarballs -- doh
06-11-23 iffe.sh: add -F, --features=feature-test-header
06-11-11 make.probe: favor lib64 over lib for hosttype==*64
06-10-31 make.probe: add "-ignore-source-dir -iquote" test
06-10-31 iffe.sh: add status{...} code block
06-10-11 regress.sh: fix DO to handle {...} (time for regress.tst?)
06-10-11 package.sh: handle already gunzip'd *.tgz
06-10-06 iffe.sh: add reference for header content tests
06-09-27 regress.sh: fix UMASK to do DO too (duh)
06-09-22 iffe.sh: drop -O for npt tests (for msvc intrinsics)
06-09-14 cc.darwin: drop -O until gcc 4.* gets its act together
06-09-11 package.sh: { cc ld ldd } intercepts check ${HOSTTYPE%.*} too
06-09-08 regress.sh: add PIPE INPUT|OUTPUT for pipe io
06-09-05 C+probe: add { probe_version version_stamp version_string }
06-09-05 make.probe: add version stamp comment, CC.VERSION[.STRING]
06-08-27 regress.sh,mktest.sh: add UMASK
06-08-25 regress.sh: add -b,--ignore-space,IGNORESPACE
06-08-25 mktest.sh: add IGNORESPACE
06-08-24 mktest.sh: handle \000 in data
06-08-24 regress.sh: handle -f* for INPUT|OUTPUT|ERROR
06-08-16 package.sh: fix 'install flat' logic
06-08-11 rt.sh: handle style=shell %K date format
06-07-17 ratz.c: fix __MVS__ FAR definition
06-07-17 iffe.sh: "header x.h" -- deprecate "include x.h" for .SCAN.iffe
06-07-17 package.sh: differentiate urls vs. assignments
06-06-27 rt.sh: add --failed, --heading
06-06-27 C+probe,TEST.mk,make.probe,mktest.sh,regress.sh: 'ulimit -c 0'
06-06-26 cc.darwin.ppc: handle -lcc_dynamic disappearance
06-06-25 mktest.sh: implement PROG
06-06-11 Makefile: add -ldbm :MAPLIB:, provide public MAPLIB.mk
06-05-06 package.sh: add PACKAGE_admin_tail_timeout
06-05-22 ratz.c: upgrade to zlib-1.2.3
06-05-09 package.sh: fix admin.db docs
06-03-11 package.sh: fix `package use - command ...'
06-03-05 make.probe: work around pedantic bash 3.1 mismatched " in `.`
06-02-14 package.sh: "results failed test" == "results test failed"
cc.sgi.*: add _AST_cc_OPTIONS parameterization, -OPT:Olimit=0
cc.linux.ia64-icc: add for Intel cc
06-02-02 package.sh: FreeBSD stuck with OS version for all arch
06-02-01 package.mk: fix locale logic (tw -d requires dir arg)
06-01-31 package.sh: require $CC only for make|test
06-01-30 package.sh,hurl.sh: use the backwards-compatible --http-passwd
package.sh: add more pdksh => /bin/sh checks
06-01-26 package.sh: wget --http-pass => --http-password
package.sh: fix wget error logic
hurl.sh: wget --http-pass => --http-password
06-01-11 package.mk: pass package.license.class to make --mam too
package.mk: variants=pattern => --variants=pattern
package.sh: Darwin rel<=7 => darwin7.ppc
package.sh: FreeBSD rel<=4 => freebsd4
package.sh: FreeBSD rel<=5 => freebsd5
05-12-07 iffe.sh: don't emit <stdio.h> if <sfio.h>|<ast.h> (XXX)
05-12-05 make.probe: disable readonly.exe core dump via ulimit -c 0
05-09-22 mktest.sh: add EXEC [ ++NOOUTPUT ++NOERROR ++NOEXIT ]
05-09-21 mktest.sh: fix --style=shell compare to ignore \r
05-09-12 TEST.mk: all --force to force %.rt regeneration
05-09-05 TEST.mk: regenerate from %.rt only if newer, :SAVE: %.tst
05-08-25 mktest.sh: add
TEST.mk: add %.rt=>%.tst for mktest
05-08-18 package.sh: 'package host cpu' now checks $NPROC first
05-07-17 iffe.sh: add { define extern include print } ops
iffe.sh: accept output{...}end output on success only -- doh
05-07-01 package.sh: add TARPROBE for tar B flag probe
05-06-24 package.sh: fix binary read chmod via *.sum
05-06-06 package.sh: fix KEEP_HOSTTYPE logic to handle synthesized types
05-06-01 make.probe: verify that cc_pic works for hosted cc
cc.lynxos.ppc: make -mshared the default
package.sh: note $INSTALLROOT/bin/@(cc|ld|ldd) installation
05-05-25 make.probe: add CC.INCLUDE.LOCAL instead of -I- in CC.DIALECT
05-05-24 iffe.sh: really fix grouping logic -- with tests this time
package.sh: pipe/socket configuration mismatches => use /bin/sh
05-04-28 TEST.mk: add $(TESTS)
05-04-19 package.sh: package results test uses rt if possible
iffe.sh: fix 'op var - ... - ...' grouping logic
05-04-15 rt.sh: handle autom4ate style
05-04-11 regress.sh: fix unit name when command line unit also specified
rt.sh: handle all AST package test output formats
package.sh: fix make docs for options passed to underlying make
05-04-08 package.sh: cp -p makerules.mo to $OK to preserve mtime
regress.sh: add "TITLE name" to change TEST output title
05-04-01 rt.sh: add pretty make test + regress.sh wrapper
05-03-29 package.sh: test -e path => test -f path -o -d path
05-03-24 make.probe: fix CC.PICBIG probe to prefer -fPIC over -fpic -- doh
05-03-19 mamake.c: command line name=var also defines name.FORCE=var
05-03-11 regress.sh: unset LC_ALL when LC_* EXPORT'd
package.sh: old make.out saved in circular make.out.[1-9]
mamake.c: sync with nmake :W=O:
05-03-01 package.sh: fix flat hierarchy initialization
package.sh: admin action now properly resets sibling remote logs
package.mk: relax unknown/unwritten package messages to warnings
package.sh: handle space in command line name=value
make.probe: add MVS -Wc,dll,exportall,longname,rent to CC.DLL probe
05-02-24 package.sh: hosttype *.powerpc => *.ppc
cc.lynxos.ppc,ldd.lynxos.ppc: add
05-02-22 mamake.c: fix { -G --debug-symbols -S --strip-symbols } MAMAKEFLAGS bug
05-02-20 probe.win32: handle /platformsdk mount
05-02-19 package.sh,package.mk: add write tst for tgz in tst subdir
05-02-18 package.sh: accept cc -dumpmachine with 0 or 1 -
05-02-14 package.sh: handle multiple architectures per host in admin.db
Makefile,package.sh: honor $INSTALLROOT/bin/.paths overrides
package.sh: normalize trailing [-_]bits in host type
iffe.sh: some ksh-compatible shells don't do *(pattern)
05-02-11 iffe.sh: back out 05-01-11 child process stdin hijack
cc.lynxos.i386: -dynamic instead of -static default
05-02-10 package.sh: cyg usr/doc => usr/share/doc
05-02-08 package.sh: drop -m with pax -- delta bug fixed 2005-02-08
iffe.sh: work around old bash 0<... redirection bug
05-02-06 package.mk: source.tgz: update generated files only when they change
05-02-02 *.sh,*probe: IFS may be unset and { ash bsh } don't on startup -- wow
05-01-11 package.sh: update setup docs to include authorize+password
package.mk: fix .source.cyg final directory edit
package.mk: notice=1 for conspicuous empty NOTICE file
WWW.mk: fix *-index.html installation
filter.sh: retain input file suffix in tmp copy
mamexec.c: fix non-contiguous "exec" bug that skipped lines
iffe.sh: fix candidate lib test to try grouping subsequent libs
iffe.sh: fix child process stdin hijack that skipped input lines
iffe.sh: --shell=osh to force read -r compatibility command
iffe.sh: chop iffe input leading space before # for KnR compatibility
05-01-05 package.sh: add ${TAR} ${TARFLAGS} and tar B flag for pipes
mamake.c: fix makefile scan to ignore lib*.[hH]
iffe.sh: immunize function/symbol tests from aggressive -O
04-12-28 WWW.mk: add :WWWPAGE: faq.*.mm index generator
04-12-21 ratz.c: make sure tmp dir is writable -- doh
04-12-08 iffe.sh: fix dat test for aggressive -O
04-12-01 iffe.sh: add `include file' to pull in #define's for `exp'
04-11-11 package.sh: default MAKESKIP is "*[-.]*"
04-10-22 ratz.c: change docs to note zlib license
mamake.c: handle --debug-symbols and --strip-symbols
package.sh: make (debug|strip)=1 => --(debug|strip)-symbols
package.mk: add :LICENSE: => package.license.class
mamake.c: fix recursive order logic
04-10-18 package.mk: add :LICENSE:, :OMIT: to omit package subdirs
04-10-11 package.sh: add 'authorize name' and 'password password'
04-10-01 iffe.sh: double check $static link with ! $static
Makefile: add BUILTIN_LIB to $INSTALLROOT/bin/.paths
make.probe: add CC.DIALECT EXPORT={ALL,REF,EXT,DLL}
package.sh: add BUILTIN_LIB to $INSTALLROOT/bin/.paths
04-09-21 package.mk: $(init)$(name) is now an implicit prereq
04-09-09 package.sh: copy makerules.mo to $INSTALLROOT/bin/ok
04-09-01 package.mk,package.sh: rename *.txt => *.README
package.mk: add the runtime package type (no *.[ah])
iffe.sh: fix key test reports
04-08-26 Makefile: { add m2.c m3.c } -lm tests for { frexp[l] ldexp[l] }
04-08-11 package.mk: handle HOSTTYPE for Solaris > 9
package.sh: add `checkaout proto' for { make view }
package.sh: check for { md5sum md5 }
iffe.sh: add {if|elif|else|endif} test ...
iffe.sh: add 'exp - expression' and '( expression )'
iffe.sh: add 'name = test ...' user defined macros
iffe.sh: add '! test ...' negation
TEST.mk: add implied { .c .sh } generated prereq
cc.darwin.ppc: handle 10.3 -dylib mess
04-08-01 package.mk: let include handle nested requirements -- duh
04-07-31 package.sh: attempt a second ping before admin assumes host down
04-07-26 package.sh: fix hp.ia64 HOSTTYPE
04-07-23 probe.win32: generalize #include dir order search
04-07-17 regress.sh: add INPUT -x for chmod +x
04-07-01 regress.sh: TMP => TWD
04-06-29 regress.sh: put COMMAND in $TWD too
04-06-21 regress.sh: mkdir -p INPUT and OUTPUT intermediate dirs
TEST.mk: add :TEST: -- to disable .c .sh search
04-06-18 TEST.mk: add .SCAN.tst
04-06-17 regress.sh: TEST returns true if active, false otherwise
regress.sh: add CD to change test pwd from $TWD
04-06-16 regress.sh: add TWD for ./unit.tmp override
regress.sh: DO now flushes previous test
regress.sh: INPUT and OUTPUT handle -f for printf instead of print
04-06-11 package.sh: make sure $INSTALLROOT/bin is in front of $PATH
package.sh: skip nmake if older than 2000-10-31
04-05-20 package.sh: fix arg vs. package parse with - or '' to disambiguate
04-05-11 package.sh: package verbose update lists closure for package setup
package.sh: add src/lib/libardir to nmake proto bootstrap
regress.sh: probe for rm -u vs. chmod -R u+rwx
04-05-01 package.sh: $CC must be C, not C++; allow release command on $PATH
04-04-15 make.probe: check probe_libdir false positives
package.sh: add lib/package/*.lic src package subdirs
package.mk: add mamfile=0 to inhibit Mamfile generation
iffe.sh: config name_DECLARED => HAVE_name_DECL
iffe.sh: fix mac to handle default value
04-04-11 iffe.sh: normalize sed [\\\\/] quoting
04-04-04 package.mk: only checksum generated tarballs
mamprobe.sh: add STDCHMOD
04-04-01 C+probe: set export LANG=C for uniform error messages
make.probe: another CC.STDLIB tweak
package.sh: fix regress core dump pattern, expand [a-z] match ranges
04-03-31 Makefile: add intl :MAPLIB: test
make.probe: fix CC.STDLIB search; drop CC.* path duplicates
04-03-28 iffe.sh: drop unused exec $stdin<&0 dup
04-03-25 Makefile: add iconv :MAPLIB:
package.sh: use ${PING:-ping -c 1 -w 4}, allowing admin.db override
04-03-24 package.mk: add *.md5 checksum for each *.(c|exe|tgz)
package.sh: update base change on md5 sum instead of size
iffe.sh: adjust case label \ and keyword quoting for ancient /bin/sh
04-03-22 probe.win32: ncc => nld
04-03-19 CONVERT.mk: change the instructions and old source dir default
package.mk: fix recurse=list check
package.mk: add *.md5 checksum for each *.(c|exe|tgz)
package.sh: fix update base/delta/sync existence check
04-03-18 iffe.sh: -d2 does not remove core dumps on exit
04-03-17 package.sh: fix make recurse arg/action order
04-02-29 package.sh: add regress action to compare current and previous tests
package.sh: fix sgi.mips[23] HOSTTYPE test for old IRIX cc
package.sh: add `export variable ...'
package.sh: admin action now handles host name with non-id chars
package.sh: non-numeric M T W in admin.db disables that action
package.sh: fix admin write binary local vs. shared clash
cc.hp.pa: add _AST_CC_hp_pa_DEFAULT=+DAportable
cc.hp.pa64: sync with cc.hp.pa
cc.ibm.risc: -bnolibpath => -blibpath:/usr/lib:/lib
probe.win32: sync with make.probe
make.probe: fix last chance dynamic test
make.probe: add hp.pa CC.EXPORT.DYNAMIC -Wl,-E
make.probe: add ibm.risc CC.EXPORT.DYNAMIC -bexpall
make.probe: move probe_dll_def to the end of probe_dll
package.mk: capture subcomponent mamfile recursion
04-02-24 make.probe: strip "..." from cc/ld traces
iffe.sh: add ``set [no]define'' to disable macro #define/#undef
04-02-23 make.probe: rework CC.LD search
04-02-14 make.probe: add CC.EXPORT.DYNAMIC for main dynamic sym export
make.probe: resurrect CC.PIC with separate semantics from CC.DLL
make.probe: add CC.SHARED.LD for CC.SHARED linker
C+probe: clear DISPLAY to stifle interactive windows
04-02-11 iffe.sh: handle ``siz void*'', add cross{ ... }end
make.probe: add { CC.AR CC.SIZE }, fix cross command search
cc.darwin.ppc: change $cc => $CC for old ksh + libast conf bug
04-02-09 make.probe: drop -nostartfiles from CC.SHARED for C++
04-02-04 package.sh: fix cross compilation bug that mixed binary formats
04-02-02 package.sh: package admin now ditto's bin/package too
04-01-30 cc.sgi.mips3: drop warning 3421
04-01-11 regress.sh: output label#count for tests in loops
04-01-05 regress.sh: fix bug that ignored the first SAME
04-01-04 crossexec.sh: fix typo that did not recognize rcp
03-12-19 mamake.c: add `foolib:foo:libfoo' to recurse()
03-10-11 regress.sh: add EXPORT, export COLUMNS=80 for message consistency
03-09-23 ratz.c: fix tar header number parse bug that skipped to next number
regress.sh: rm cleanup now handles files matching -*
03-09-11 iffe.sh: add unnamed { ... } blocks
regress.sh: add COPY from to, like MOVE but comparison still done
regress.sh: rm -rfu to handle test dirs w/o u+rwx
03-08-14 Makefile: add hello.c to the manifest
03-08-11 package.sh: fix `html binary' generation
03-06-21 package.sh: fix INITROOT initialization bug
package.sh: make sure admin logs exists before tail'ing
03-06-11 probe.win32: fix $(BINDIR) typo that expanded in sh instead of make
cc.mvs.390: return code 4 yields exit code 3 but it's *really* ok
package.sh: fix onpath function global var conflict
make.probe: add CC.DIALECT { GNU -dD }
package.mk: add Mamfile to lcl manifest
03-06-10 package.sh: fix setup action typo that only checked the INIT package
package.sh: *.s390x => *.s390-64
03-06-09 package.mk: add cyg :POSTINSTALL:
03-06-08 make.probe: fix CC.STDLIB logic
hurl.sh: add User-Agent identification
package.sh: tweak source and binary installation instructions
cc.hp.pa,ld.hp.pa: +-Wl,+cdp,${INSTALLROOT}/lib/: drops abs lib paths
ldd.hp.pa: add
03-06-06 package.sh: fix $INSTALLROOT/bin/ldd check
make.probe: add CC.STDLIB verification
03-06-04 make.probe: add +forceread +noforceread
03-05-11 hurl.sh: handle http://host:port/path
03-05-06 package.sh: fix setup action PACKAGEROOT and INIT logic
03-05-05 package.mk: fix Cygwin tarball names
03-04-30 package.sh: move (cc|ld|ldd).$HOSTTYPE updates from Makefile
03-04-27 make.probe: fix MVS CC.PREFIX.SHARED "lib" => ""
make.probe: add CC.DLL.DIR = $(BINDIR) or $(LIBDIR)
make.probe: add { CC.LD.LAZY CC.LD.NOLAZY CC.LD.RECORD CC.LD.NORECORD }
probe.win32: sync with latest CC.*
03-04-25 mamprobe.sh: add args to `. $makeprobe' for ancient sh
03-04-23 package.mk: fix dup "covered by" licenses
03-04-22 probe.win32: CC.DIALECT += "LIBPP -I-" for all cc's
package.sh: fix admin write binary tarball snarf
03-04-21 package.mk: package covered *.@(pkg|lic) too
03-04-15 package.mk: don't generate incremental archives for lcl
package.mk: add incremental=[source:1 binary:0] archive control
package.sh: generate $INSTALLROOT/bin/cc wrapper for CC != cc
package.sh: admin must ditto lib/package/*.@(pkg|lic) too
mamake.c: ignore time of ignore prereqs
mamake.c: -D2 lists propagated times
03-04-11 package.mk: tidy up cyg tarballs
package.sh: fix old shell clash between get() and $get
03-04-05 package.mk: restore *.inx generation somehow lost during cyg additions
package.sh: add pthread_num_processors_np() last resort for CPU count
package.sh: use `make believe' to accept mamake generated files
package.sh: handle `make [make-flags] [target ...]'
mamake.c: ignore -e
03-03-21 package.mk: fix cyg old make typo
package.sh: switch to `package setup' instructions
03-03-19 package.sh: add registry checks for `host cpu'
package.sh: `results failed' now lists core dump messages
03-03-17 package.sh: on Cygwin verify 'ntsec binmode' in $CYGWIN or die
Makefile: install gcc wrapper if no cc
package.mk: add :DETAILS: { :README: :EXPORT: :INSTALL: :TEST: } ops
03-03-12 package.mk: add :DETAILS: for style-specific details
03-03-11 package.sh: add beta setup/update support
TEST.mk: add (TESTCC) prereq for .sh tests
03-03-07 hurl.sh: add
03-03-06 iffe.sh: fix lib Win32 test Cygwin vs native incompatibility
iffe.sh: change internal stdio.h guard to handle C++ inline vs. macro
03-03-03 package.sh: check for curl or wget for update
package.sh: add setup action == update read make
package.sh: fix packageroot() typo that showed up in non ~user shells
mamake.c: treat name+=value args like name=value
mamake.c: add ${var?*|value?match?no-match?}
mamake.c: fix archive vs. dynamic bind logic
03-02-28 package.sh: add the "cyg" (Cygwin) package type
package.mk: add "cyg" stubs, :CATEGORY: for category name(s)
03-02-25 mamake.c: add -D4 system(3) debug trace
03-02-24 package.mk: change --mismatch to --corrupt=accept
03-02-14 ratz.c: add _WIN32 setmode([01],O_BINARY) and fopen "rb"/"wb"
03-02-12 Makefile: handle getconf LIBPATH with host pattern
03-01-31 package.mk: fix .lic search
03-01-30 package.sh: handle { INIT ksh nmake } already installed elsewhere
package.sh: admin handles command outside of $PACKAGEROOT/bin
Makefile: install $(INSTALLROOT)/lib/make/package.mk
03-01-28 package.sh: admin remote commands on one line to please syslog
03-01-23 probe.win32: borland and mingw32 tweaks
03-01-22 package.sh: fix $CC test to ignore set -x trace -- duh
03-01-16 ditto.sh: tw --chop on by default
03-01-14 package.sh: use /bin/cp to copy previous binaries to bin/ok/
package.sh: admin now initiates remote exec and copy from local host
03-01-12 package.sh: handle admin "xxx:" default root
03-01-03 probe.win32: add /usr/include/borland path truncation workaround
02-12-10 iffe.sh: add <&$nullin >&$nullout to checkread() $cc
02-12-06 probe.win32: fix inlcude => include typo, add lcc lib
probe.win32: CC.MAKE.OPTIONS = nativepp=0
02-12-04 mamake.c: fix ${foo-bar} to expand foo if defined
02-11-28 probe.win32: add C++ and -I- CC.DIALECT checks
02-11-26 package.sh: package release now checks for second level files
02-11-22 package.sh: update action now uses HTTP/1.0
02-11-21 probe.win32: update the vc include dir test
02-11-20 make.probe: fix CC.LD.ORIGIN typo that expanded make var
02-11-13 packahe.mk: fix list.install => list.installed typo
02-11-12 make.probe: add CC.LD.ORIGIN for a.out origin dir relative dll search
make.probe: add CC.LD.STRIP for link time a.out strip
package.sh: fix package_use vs. PACKAGE_USE check
02-10-24 WWW.mk: fix bug that required a :WWWBIN: assertion to post
02-10-23 mamake.c: fix uninitialized time in make()
ratz.c: fix meter buffer overflow
02-10-20 package.sh: fix lib/probe/C/make/probe update test
02-10-18 probe.win32: update for mingw
make.probe: add bash workaround to SHELLMAGIC test
package.sh: work around yet another Cygwin hassle
02-10-17 iffe.sh: short circuit ID check for *[-+/\\]*
02-10-08 regress.sh: unset FIGNORE to avoid rm . errors
package.sh: unset FIGNORE to avoid rm . errors
package.sh: $CC must at least compile and executable hello world
02-10-04 package.sh: $INSTALLROOT/lib/package/tgz=>$PACKAGEROOT/lib/package/tgz
package.mk: $(ED) => $(STDED), $(EDFLAGS) => $(STDEDFLAGS)
iffe.sh: add identifier checks for tests that (implicitly) require them
iffe.sh: disambiguate a few --config macros
02-10-02 iffe.sh: fix shell=bsh `hdr a/b'
02-09-30 package.sh: handle chmod of -* files
package.sh: verify that $SHELL is Bourne compatible
package.sh: tighten PACKAGE_USE logic PATH,LIBPATH,etc. validation
iffe.sh: fix bug that didn't define mac variable on success
02-09-22 package.sh: handle admin_action=ditto
iffe.sh: --config sizeof(foo) macro is SIZEOF_foo
iffe.sh: fix long.long test so it doesn't defeat UWIN "typ long.long"
mamprobe.sh: convert $("foo") nmake string constants
02-09-21 mamprobe.sh: "-" info-path writes probe info to stdout
02-09-11 make.probe: move from nmake src to be part of mamprobe.sh
mamprobe: generate from mamprobe.beg C.probe make.probe mamprobe.end
mamake.c: pass cc absolute path to mamprobe
package.sh: generate mamprobe -- yuk (at least it's confined to INIT)
iffe.sh: lcl,nxt: drop default sys/ check
ditto.sh: tw --logical by default; add --physical
02-09-10 package.sh: SHELLMAGIC creeps into package too -- duh and fooey
02-09-09 ditto.sh: test that remote .profile exists before sourcing
02-09-06 package.sh: don't ditto nfs junk
ditto.sh: --show now lists directory ops instead of enumerating all
02-09-05 ditto.sh: add --remote={rsh|ssh}
package.sh: add admin [[{rsh|ssh|-}]:]directory
02-09-02 iffe.sh: change 'print -r --' to 'print -r -' for ksh86 compatibility
02-09-01 cc.unix.mc68k: add for ancient 3b1
02-08-22 package.sh: fix component() to test for components -- duh
Makefile: add LICENSE:.DONTCARE to workaround mam
02-08-11 iffe.sh: provide defaults for LD_* additions
02-08-07 ratz.c: change -m to use * instead of non-portable inverse video
02-07-17 mamprobe.sh: close tmp file in trap before rm for Cygwin
package.sh: fix "type" to handle i1586 (P4)
package.sh: add the view action
02-06-28 package.sh: handle multiple packages for release action
02-06-27 package.sh: catch sol*.sparc=>sol*.sun4 when CC=gcc
02-06-14 package.sh: fix admin_action to not include qualifiers
package.sh: fix help/html doc typo
02-06-11 package.sh: fix ditto update doc to `PACKAGEROOT field matching *:*'
02-06-07 WWW.mk: change substitute $("\n") to \n
02-06-06 package.sh: clarify output streams for help/html
02-05-22 mamake.c: fix executable file check to use (S_IXUSR|S_IXGRP|S_IXOTH)
02-04-04 package.sh: fix update to differentiate *.sun4 and sun4
02-03-27 package.sh: yacc/bison warning only if both missing
02-03-24 mamake.c: all shell actions wrapped with -c to avoid #! problems
02-03-23 package.sh: recover $PACKAGEROOT/bin/package if not in INIT package
package.sh: precheck $CC, not `cc'
package.sh: fix install to use pax -ps to preserve setuid/setgid
package.sh: fix install to use list.installed for existing files only
02-03-17 package.sh: fix PAX initialization that was sometimes omitted for read
package.sh: fix update delta sync fetch
02-02-14 iffe.sh: fix macro{ }end docs to include "
iffe.sh: add dfn to extract #define from headers
iffe.sh: handle nxt #include ok but no line sync
iffe.sh: drop local header clash logic
iffe.sh: add -X, --exclude=dir to exclude -I dirs
iffe.sh: lcl,nxt now generate <...> headers instead of "..."
package.sh: admin.db root dir matching -* disables host
package.mk: fix package.src.pat typo -- too many )
package.mk: add { :COVERS: :DESCRIPTION: :REQUIRES: }
package.sh: handle { :COVERS: :DESCRIPTION: :REQUIRES: }
Makefile: move proto.c generation to the proto component dir
02-02-02 execrate.sh: add for .exe challenged Win32 systems/commands
mamprobe.sh: add STD* commands/flags
mamake.c: update mamprobe info when older than mamprobe executable
package.sh: move ed/ex workaround to mamprobe.sh
package.sh: fix `host type' bug that incorrectly assumed sun4 for sol
package.sh: add execrate(1) hooks for challenged systems
package.sh: add check for { cc ar nm yacc/bison } before make
ratz.c: fix "rb" vs. "r" macro tests
iffe.sh: add nxt, similar to lcl but defines _nxt_foo for #include
iffe.sh,package.sh: remove variable from sccs,cvs ident strings -- duh
02-01-24 C+probe: check CC.DYNAMIC to handle cc that accept but ignore -B*
iffe.sh: handle 'mem struct.a.b'
02-01-22 iffe.sh: cache (internal) `foo vs. struct foo' test results
package.sh: uts.370 => uts.390
02-01-18 package.sh: fix uts hosttype
02-01-17 package.sh: add 'results failed ...' to list failures only
package.sh: change ARCH internal var to all_types to avoid env conflict
iffe.sh: fix hdr/lib precheck that missed some -- ouch
iffe.sh: fix noexecute test that forgot to check compile first!
02-01-15 ratz.c: fix path[] type typo
02-01-01 package.mk: tighten license search
02-01-08 package.sh: `pwd` => ${PWD:-`pwd`}
package.mk: expand license file pattern match
02-01-04 iffe.sh: fix `exp name "value"' bug that duped "value"
iffe.sh: fix initial <sys/types.h> check to honor --config
01-12-25 iffe.sh: fix bug where -o file restored old file
01-12-23 package.mk: uniq the closure lists
01-12-07 ratz.c: fix --meter to retain paths containing " -- "
01-11-30 ratz.c: use sear_system() to execute; should work on all windows
01-11-28 ratz.c: fix sear_rm_r() to check SetCurrentDirectory() status
01-11-26 ditto.sh: drop n+=v for ksh compatibility
01-11-21 ditto.sh: add rsync script replacement [hey, it works!]
package.sh: add [ditto]:directory notation to admin.db
01-10-31 package.sh: handle *.sum paths with embedded space
package.sh: change executable() to onpath()
package.sh: executable([!] foo) replaces test [!] -x foo (.exe hack)
package.sh: add os2 fix to `host type'
mamake.c: add .exe hack
iffe.sh: fix intrinsic function lib test
mamprobe.sh: update pic probe to match make.probe for linux.ia64
01-10-30 package.sh: make action skeleton view now checks subdirs
01-10-20 package.sh: don't recurse into leaf dirs matching $MAKESKIP
package.mk: tarball package.notice replaces `license accepted' prompt
package.sh: eliminate `license accepted' prompt
package.sh: add update to download latest from a url
package.sh: use builtin arithmetic when we know it's ksh
iffe.sh: unkown -> unknown
01-10-18 package.sh: convert to YYYY-MM-DD delta releases instead of NNNN
package.mk: convert to YYYY-MM-DD delta releases instead of NNNN
ratz.c: fix -m for paths containing \f\n\r\v
01-10-16 ratz.c: _SEA_* => SEAR_*
ratz.c: preserve stdin for sear_exec()
ratz.c: add recursive sear_rm_r() to sear_exec() tmp dir cleanup
01-10-10 mamprobe.sh: add mam_cc_SHELLMAGIC
package.sh: add nfs wakeup call to admin to avoid stale file handles
01-10-04 cc.darwin.ppc: -flat_namespace is not longer the default (huh)
01-10-01 package make: prepend $INSTALLROOT/bin/ok to PATH
package read: save cpy of bin/package when reading the INIT package
mamprobe.sh: allow cc path with optional arguments
01-09-24 Makefile,package.sh: add $INSTALLROOT/bin/.paths initialization
01-09-19 package.mk: add recurse to list.package.*
package.sh: bootstrap build nmake with _BLD_STATIC for _WIN32
01-09-11 ratz.c: add _SEA_SKIP & _SEA_COMMAND for self extracting archives
01-09-07 package.mk: fix output capture to not generate files names with spaces
01-09-07 package.mk: fix delta release number search
01-08-11 package.mk: handle single gz executable packages (e.g., for ksh)
package.sh: fix package install to require nmake only if no *.sum
iffe.sh: drop ancient menu and prompt actions; check ./hdr.h clash
01-07-17 package: fix use cross compile test to generate files in /tmp
01-06-27 ratz: handle hard and soft links if possible
01-06-07 Makefile: fix :MAPLIB: for sco
01-05-31 crossexec.sh: add
iffe.sh: add -x crosstype to run crossexec
iffe.sh: exp test now handles pass{}end fail{}end yes{}end no{}end
package.sh: add package host canon external-host-type-name
package.sh: fix `use USER' lookup for shells that support ~USER
cc.*: add -dumpmachine to dump target HOSTTYPE
01-05-18 iffe.sh: drop $HOME/tmp/t.sh debug trace -- oops
01-05-01 mamake.c: scan() now handles :PACKAGE: foo:command
01-04-26 *.sh: expand [a-z][A-Z][0-9] for non-contiguous character codes
iffe.sh: fix run *.sh for shells that don't $* across . command
cc.mvs.390: recode for /bin/sh
01-04-25 package.mk: include non cc-g variants by default
package.sh: *[._]* => *?[_.]* for mvs.390 /bin/sh
01-04-24 TEST.mk: no tests for VARIANT=="DLL"
01-04-22 package.mk,package.sh: tarball text members are ASCII encoded
01-04-18 package.mk: allow package name to be the same as one of its components
cc.mvs.390: handle .C .cpp .cxx
cc.mvs.390: compensate for -o that does not overwrite
01-04-01 regress: fix SAME that just skipped it -- we should regress regress!
iffe: fix bug that didn't emit _hdr_foo for internal hdr tests
iffe: fix lcl bug for cc -E that doesn't emit line syncs
ratz: add ASCII=>EBCDIC conversion for text archive members
mamake: fix buffer overlap bug that clobbered the probe file path
01-03-17 iffe: handle : separator as first arg
01-03-15 mamake.c,ratz.c,release.c: add <stdlib.h> and <string.h>
01-02-26 iffe.sh: fix bug that omitted runtime #define for `mac' op
01-02-22 cc.ibm.risc: handle SF_CLOSE clash in <sfio.h>
01-02-14 cc.sgi.mips3,cc.sgi.mips4: handle -mips2 -mips3 -mips4 for cross cc
C+probe: quote "$cc" when it's an argument!
mamake: execute actions with $SHELL, ignored signals back to default
package.sh: nmake check error output to /dev/null
package.sh: fix INIT a.out updates for knr cc
package.sh: package list now handles large tgz dirs
package.sh: *-ok executables moved to ok/* for *.dll systems
iffe.sh: change "exec >&-" to "exec >/dev/null" else Linux mkdir fails!
mamake: handle `bind -lx [dontcare]'
01-02-12 ratz.c: fix _PACKAGE_ast includes
package.sh: $HOSTTYPE env overrides if $PACKAGEROOT/arch/$HOSTTYPE/
package.sh: $CC ^HOSTTYPE=[A-Za-z_0-9.]*$ overrides HOSTTYPE
iffe.sh: fix dat code that used previous $tmp.exe
iffe.sh: fix dat code for _DLL imports
01-02-09 iffe.sh: add copy() for shells with the disappearing here doc bug
01-02-08 Makefile: guard against null $(CC.HOSTTYPE)
01-02-06 Makefile: separate out cc,ld,ldd workarounds (so they will be packaged)
01-02-02 package.sh: fix package use for $INSTALLROOT != */$HOSTTYPE
package.sh: create intermediate recursion makefiles when needed
package.sh: add $SECONDS to the DEBUG trace prompt
01-01-01 ratz.c: #ifdef for UWIN ncc
iffe.sh,package.sh: check PACKAGE_PATH for local installations
package.sh: add psrinfo for osf.alpha host cpu
package.sh: change pax --meter probe; some hang on /dev/tty
package.sh: fix `install flat ARCH'
mamake: eliminate loops from scan order
C+probe: add probe_verbose -V for AIX cc=xlc
cc.ibm.risc,ldd.ibm.risc: add
package.mk: list refs to top-level licenses only
package.mk: add local link table to change log html
00-12-25 package.sh: `no package archives' is a hard error, duh
package.sh: reorder host type logic for lame shells
mamake.c: getcwd => getwd for NeXT -- how about posix==default guys
iffe.sh: really gross workaround for NeXT -lposix stdout null's
iffe.sh: handle cc -E that insists on compiling
00-12-15 iffe.sh: ancient sh function call blows $*; call only when $# == 0
*.sh: `getopts 2>/dev/null` => `(getopts)2>/dev/null` for ancient sh
package.sh: fix LD_LIBRARY*_PATH initialization
cc.next.m68k: add for _POSIX_SOURCE and linker multiply defined syms
00-12-12 ratz: add --meter
package.sh: a few VPATH fixes
Makefile: don't override *.mips* cc if -version not accepted
00-12-11 package.mk: *.inx now contains name=value
00-12-07 package.sh: handle PC netscape . => _ pathname mangle
WWW.mk: .tar.gz => .tgz
00-11-27 package.sh: add checklicense() to do license checks at read time
package.mk: change component list from preformat to table
00-10-31 package.mk: *.pkg must assert closure
package.mk: add cc- variants to list.package.binary
package.sh: omit dups from package list
package.sh: invalid arg gives one line Usage
package.sh: relax checkaout checks for non-owners
package.sh: package use sets NPROC if not already set or [01]
proto.c: add $(INSTALLROOT)/include/ast hack
00-10-26 WWW.mk: add .SOURCE rhs to :WWWPAGE:
00-10-25 package: fix install
package.mk: add list.install
00-10-22 regress: fix VIEW to skip empty dirs
00-10-19 package.mk: $(PACKAGEROOT)/bin/nmake => $(PACKAGEROOT)/bin/manmake
iffe: validate #define identifiers
00-10-18 C+probe: Mac OS X additions
package: add DYLD_LIBRARY_PATH initialization
add ldd.$(CC.HOSTTYPE)
00-10-01 iffe: handle -I* -L* options
00-09-21 mamake: add libxxx and xxx to makefile ordered prereqs
00-09-19 C+probe: add probe_longlong
00-09-11 package: drop manmake and $PACKAGEROOT/bin/nmake
00-09-08 iffe: verify that $cc is a C compiler
00-06-14 mamprobe: fix win32.* probe
mamake: fix bug that used lower view path for generation
package: don't clobber $PACKAGEROOT/bin/nmake
00-06-01 C+probe: fix stdinclude *again*
package: fix write delta source to use default pax format
package: add disambiguating bias for sgi.mips3 over sgi.mips4
package.mk: fix for directory content packages lib ast-locale
00-05-01 iffe: fix invalid _LIB_ macro identifier
00-04-11 C+probe: uniq stdinclude and stdlib, fix usrinclude
00-04-01 regress: fix explicit OUTPUT bug that didn't compare with expected
00-03-17 package: all archives are .tgz for binary download
package: $(PACKAGEROOT)/LICENSES/* in source and binary archives
package: implement install and verify actions
iffe: add exp, pth file dir ..., fix lib - -lfoo, fix lib - - -la -lb
iffe: -L* must affect LD_LIBRARY* hacks for .exe tests -- yuk
package.mk: add *.pkg :INDEX:
00-03-07 package: add admin action
00-03-06 makefile: install optional make probe override script C+make+probe.lcl
00-02-14 --- release 1.0 ---
ratz: treat "foo/" as a dir, not a regular file
package: clarify source and binary installation instructions
package: fix so binary packages can install without cc
package: "ratz" now a non-archive package (the only one) for bootstrap
package: handle VPATH=a:b arg
package.mk: "ratz" package adjustments
Makefile: use :PACKAGE_INIT: to support binary INIT packages
WWW.mk: add :WWWALL:
C.probe: fix .so check that let .dll slip through
iffe: fix config sh var assignment for HAVE_member_IN_struct
iffe: fix config sh var assignment for symbol_DECLARED
package: delay PATH export until dll hack exports complete
package: don't forget binary package $(INSTALLROOT)/lib(32|64)
package: add delta change log for source packages
00-02-10 mamprobe: add mam_cc_DLLBIG
package: fix spelling typos
package: add html help output
package.mk: beef up source and binary help => html
00-02-08 package: mkdir man/man[138] in the new arch to cover MAM bug
00-01-28 package,release: add -rcount to release
package: fix Linux "host cpu" and "host rating"
package: copy *.lic to $PACKAGEBIN for "make" and "write binary"
package: fix 'release change log' case match
00-01-24 package: add copyright action
mamprobe: add -D_BLD_DLL to mam_cc_DLL
00-01-11 package: tsort for package write
package: early verification that $CC works
package: add non-interactive command arg for use action
proto: fix -C intermediate mkdir()
mamprobe: unixware.i386 ksh workaround
C.probe: move hosttype to C.probe (with unixware.i386 workaround)
WWW.mk: fix mm2html option quoting
WWW.mk: add .SCAN.mm
WWW.mk: don't force static=1; grab dll's instead
*.sh: fix getopts test to handle botched implementations like osf.alpha
iffe.sh: fix read -r test
99-12-25 iffe: tweak verbose messages
iffe: hand code non-optget getopts parse
iffe: fix bash quoting bug again
iffe: do test -w . after option parse
package: fix PACKAGEROOT search
99-11-19 --- release 0.2 ---
99-11-19 first working package & friends
99-10-31 change from lib0ast to INIT; add MAM and package bootstrap
hostinfo: gobbled by package
99-10-01 iffe: add --config, yes{...}end no{...}end, fix read -r workaround
99-09-27 iffe: add --all --verbose, --* set options
99-09-22 regress: -v disables long line truncation
99-09-11 WWW.mk: WWWDIR and MM2HTMLINFO are now lists searched in $(HOME)
99-08-11 hostinfo: fix type sgi.mips4
99-06-24 WWW.mk: add
99-06-08 hostinfo.sh: ${TMPDIR:-/tmp}
99-06-07 TEST.mk: add
99-06-01 iffe: add `siz type' for _siz_type == sizeof(type)
99-05-11 hostinfo,iffe,regress,use: long options
99-05-01 C.probe: fix over aggressive stdinclude, e.g., /usr/include/machine
99-04-01 hostinfo: sgi.mips? -o32 and -n32 checks
iffe: check that . is writable
99-03-17 hostinfo: fix for cc not found
dl.c,hello.c,m.c: headers in conditionals to force .DONTCARE
C.probe: extra check for include dirs pulled in by <sys/types.h>
99-03-03 regress: add `UNIT - ...' for extra args
Makefile: add (_hosttype_) prereq for cc
99-01-23 hostinfo: tweak rating, use /proc/cpuinfo if there
99-01-11 C.probe: shlib before lib, /usr before /
98-12-25 iffe: work around win32.alpha intrinsic clash with -O
98-11-11 regress: fix UNIT PATH lookup
98-11-01 regress: add PROG
98-10-01 hostinfo: add unixware.*
use: export PACKAGE_*
98-08-11 C.probe: add /usr/include check (for sco CC)
hostinfo: handle UWIN uname update
98-05-01 regress: fix bug sometimes didn't list last test
98-04-01 hostinfo: add cc path arg
hostinfo: now works with /bin/sh
Makefile: strengthen -lm probe
98-01-23 Makefile: check for -ldl -lm
C.probe: handle gcc -v -E phony include dirs
iffe: fix lcl by dropping sort -u -- we need the real first
iffe: `mem x' to test if x is a non-opaque struct
98-01-11 $(INSTALLROOT)/lib32 for sgi.mips3
$(INSTALLROOT)/lib64 for sgi.mips4
add cc.hp.pa
98-01-01 cc.sgi.mips*: turn off ld library multiply defined
97-10-11 regress: add VIEW function for locating data
97-10-01 Makefile: -ldl test moved to libdll Makefile
97-08-11 regress: add MOVE
regress: add SAME
regress: use getopts
regress: `EXEC' repeats previous test
97-07-17 use: tweak PATH and LIBPATH bootstrap order
iffe: fix lcl bug that botched pathnames with embedded spaces
97-06-12 iffe: add npt `needs prototype' test
97-05-09 hostinfo: mvs.* => mvs.390
Makefile: cc.$(_hosttype_) workaround installed here
iffe: fix nolink{ ... }end
iffe: add [no]static{ ... }end for static link test
C.probe: _probe_PATH => _probe_export which must be eval'd
97-04-01 use: _RLD_ROOT set too
97-03-17 mm2html: changed inner loop
mm2html: handle .if|.ie|.el, .so
mm2html: handle different man styles
mm2html: differentiate mm/man in some non-obvious cases
hostinfo: r5000 is not mips4
97-02-14 hostinfo: validate type with cc
96-12-25 C.probe: UWIN tweaks
iffe: use `...` instead of $(...) for alpha /bin/sh
iffe: fix `typ' divide by 0
iffe: `lcl' now drops X: prefix
iffe: +l* -> -l*
iffe: eval around ${...#%...} for BSD /bin/sh
use: add sgi.mips LD_LIBRARY<abi>_PATH variants
use: add -e to list exports
iffe: lcl leaves leading [a-zA-Z]: for DOS
iffe: fix no{link|output|execute} logic
C.probe: don't automatically add /usr/include for non-hosted compilers
C.probe: don't automatically place /usr/include last
C.probe: check gcc style -v -E for stdinclude usrinclude
96-11-28 iffe: check BASH_VERSION for IFS botch
iffe: typ long.xxx only if sizeof(long xxx) != sizeof(xxx)
hostinfo: fix sgi.mips[234] tests
hostinfo: fix ncr.i386 tests
96-10-31 iffe: work around old bsh here doc bug by running separate sh
96-10-11 iffe: *.iffe and *.iff for iffe src files
hostinfo: tighten sgi.mips CPU type check
96-10-01 C.probe: add probe_libdir to catch alpha /usr/shlib
96-09-17 iffe: fix typ bug that failed for single ID types!
96-08-31 hostinfo: handle recent SGI hinv CPU changes
96-07-17 make sure sizeof(long xxx)>sizeof(xxx) for typ long.xxx
96-05-09 C.probe: drop multiple / in stdinclude
96-02-29 use: package root must have bin and lib subdir
mm2html: add
C.probe: probe_members += -whole-archive for gcc
iffe: add + fix the blasted `...'...\\...'...`
96-01-31 use: add pkg dir
hostinfo: add tandem
96-01-01 hostinfo: windows_nt|windows[0-9][0-9] -> win32
95-11-24 hostinfo: linux-aout.* for non-ELF Linux
95-11-11 use: add AIX LIBPATH
95-10-11 hostinfo: no args prints type
95-08-11 use: add
95-05-09 save original PATH in _probe_PATH
beef up library dir probe
95-04-01 use c source suffix if it still preserves the dialect
add hostinfo
add lib/hostinfo/typemap user type map
add sol.sun4 CPU count
fix C.probe to properly handle C/C++ combined compiler drivers
add NeXT to hostinfo
bummer: mach has /usr/bin/hostinfo
95-03-19 fix dialect executable test
95-03-19 --- release 0.0 ---

View File

@@ -0,0 +1,9 @@
: ar requires a non-standard option to work : 2009-10-06 :
op=$1
shift
case $op in
-*) ;;
*) op=-$op ;;
esac
/usr/bin/ar -Xany "$op" "$@"

View File

@@ -0,0 +1,9 @@
: ar requires a non-standard option to work : 2022-01-14 :
op=$1
shift
case $op in
-*) ;;
*) op=-$op ;;
esac
/usr/bin/ar -X64 "$op" "$@"

View File

@@ -0,0 +1,13 @@
: hp.ia64 cc wrapper for reasonable ANSI C defaults : 2011-01-25 :
[ /usr/bin/cc -ef /usr/ccs/bin/cc ] || exit 1
: bundled cc -- really, in the face of gcc you ship a subpar /usr/bin/cc? :
HOSTTYPE=hp.ia64
case " $* " in
*" -dumpmachine "*) echo $HOSTTYPE; exit ;;
esac
/usr/bin/cc -D_HPUX_SOURCE -D_INCLUDE__STDC_A1_SOURCE -D_INCLUDE_XOPEN_SOURCE_500 "$@"

View File

@@ -0,0 +1,13 @@
: hp.pa cc wrapper for reasonable ANSI C defaults : 2004-02-29 :
HOSTTYPE=hp.pa
case " $* " in
*" -dumpmachine "*) echo $HOSTTYPE; exit ;;
esac
_AST_CC_hp_pa_DEFAULT=${_AST_CC_hp_pa_DEFAULT-"+DAportable"}
/opt/ansic/bin/cc -Ae +e -Wl,+s $_AST_CC_hp_pa_DEFAULT \
${INSTALLROOT:+-Wl,+cdp,${INSTALLROOT}/lib/:} \
-Wl,+vnocompatwarnings "$@"

View File

@@ -0,0 +1,11 @@
: hp.pa64 cc wrapper for reasonable ANSI C defaults : 2001-02-11 :
HOSTTYPE=hp.pa64
case " $* " in
*" -dumpmachine "*) echo $HOSTTYPE; exit ;;
esac
/opt/ansic/bin/cc +D2.0W -Ae +e -Wl,+s \
${INSTALLROOT:+-Wl,+cdp,${INSTALLROOT}/lib/:} \
-Wl,+vnocompatwarnings "$@"

View File

@@ -0,0 +1,63 @@
: cc wrapper for AIX RISC xlc : 2012-04-17 :
hosttype=ibm.risc
case $HOSTTYPE in
$hosttype-64)
case " $* " in
*" -q64 "*) ;;
*) set -- -q64 "$@" ;;
esac
;;
*) case " $* " in
*" -q64 "*) HOSTTYPE=$hosttype-64 ;;
*) HOSTTYPE=$hosttype ;;
esac
;;
esac
case " $* " in
*" -dumpmachine "*)
echo $HOSTTYPE
exit
;;
esac
bin=/usr/vac/bin
cc=$bin/xlc
ccflags="-brtl -qhalt=e -qsuppress=1506-224:1506-507"
case " $@ " in
*" -G "*)
ccflags="$ccflags -berok"
;;
esac
if test -x $bin/c99
then # the xlc optimizer vintage that supports c99 is flawed and causes the AST build to fail #
case " $* " in
*" -O "*)
set '' "$@" ''
shift
while :
do a=$1
shift
case $a in
'') break ;;
-O) ;;
*) set '' "$@" $a ;;
esac
shift
done
;;
esac
$cc $ccflags "$@"
code=$?
else export PATH=/bin:$PATH LIBPATH=/usr/lib:/lib
ccflags="$ccflags -blibpath:$LIBPATH"
fi
$cc $ccflags "$@"
code=$?
case $code in
127|255) code=1 ;;
esac
exit $code

View File

@@ -0,0 +1,36 @@
: cc wrapper for AIX RISC gcc : 2012-04-17 :
hosttype=ibm.risc
case $HOSTTYPE in
$hosttype-64)
case " $* " in
*" -maix64 "*) ;;
*) set -- -maix64 "$@" ;;
esac
;;
*) case " $* " in
*" -maix64 "*) HOSTTYPE=$hosttype-64 ;;
*) HOSTTYPE=$hosttype ;;
esac
;;
esac
case " $* " in
*" -dumpmachine "*)
echo $HOSTTYPE
exit
;;
esac
cc=gcc
ccflags=
case " $@ " in
*" -shared "*)
ccflags="$ccflags -shared -Wl,-G -Wl,-berok"
;;
*) ccflags="-Wl,-brtl"
;;
esac
$cc $ccflags "$@"

View File

@@ -0,0 +1,81 @@
: lynxos.i386 cc wrapper with -dynamic default : 2005-02-14 :
HOSTTYPE=lynxos.i386
case " $* " in
*" -dumpmachine "*) echo $HOSTTYPE; exit ;;
esac
cc=gcc
link=1
static=0
set . "$@" /../
while :
do shift
case $1 in
/../) break ;;
esac
case $1 in
*.[cChHiI]|*.[cChHiI][pPxX][pPxX])
set . -D__NO_INCLUDE_WARN__ -I/sys/include/kernel -I/sys/include/family/x86 "$@"
shift
break
;;
-o) case $2 in
/../) ;;
*) x=$1
shift
set . "$@" "$x"
shift
;;
esac
;;
-static)static=1
;;
-l*) case $static in
0) static=n
set . -L/lib/shlib "$@"
shift
;;
esac
;;
-[cE]) link=0
;;
esac
x=$1
shift
set . "$@" "$x"
done
while :
do case $1 in
/../) shift
break
;;
-l*) case $static in
0) static=n
set . -L/lib/shlib "$@"
shift
;;
esac
;;
-[cE]) link=0
;;
esac
x=$1
shift
set . "$@" "$x"
shift
done
case $link:$static in
1:0) static=n ;;
esac
case $static in
n) specs=/tmp/cc$$.specs
trap 'status=$?; rm -f $specs; exit $status' 0 1 2
echo '*link: %{shared:-shared} %{static:-static} %{mshared|shared: %{static: %eerror: -shared and -static may not be combined. }}' > $specs
$cc -specs=$specs "$@"
;;
*) $cc "$@"
;;
esac

View File

@@ -0,0 +1,85 @@
: lynxos.ppc cc wrapper with -mshared default : 2005-06-01 :
HOSTTYPE=lynxos.ppc
case " $* " in
*" -dumpmachine "*) echo $HOSTTYPE; exit ;;
esac
cc=gcc
link=1
static=0
set . "$@" /../
while :
do shift
case $1 in
/../) break ;;
esac
case $1 in
*.[cChHiI]|*.[cChHiI][pPxX][pPxX])
set . -D__NO_INCLUDE_WARN__ -I/sys/include/kernel -I/sys/include/family/ppc "$@"
shift
break
;;
-o) case $2 in
/../) ;;
*) x=$1
shift
set . "$@" "$x"
shift
;;
esac
;;
-static)static=1
;;
-mshared)
static=n
continue
;;
-l*) case $static in
0) static=n
set . -L/lib/shlib "$@"
shift
;;
esac
;;
-[cE]) link=0
;;
esac
x=$1
shift
set . "$@" "$x"
done
while :
do case $1 in
/../) shift
break
;;
-l*) case $static in
0) static=n
set . -L/lib/shlib "$@"
shift
;;
esac
;;
-[cE]) link=0
;;
esac
x=$1
shift
set . "$@" "$x"
shift
done
case $link:$static in
1:0) static=n ;;
esac
case $static in
n) specs=/tmp/cc$$.specs
trap 'status=$?; rm -f $specs; exit $status' 0 1 2
echo '*link: %{shared:-shared} %{static:-static} %{mshared|shared: %{static: %eerror: -shared and -static may not be combined. }}' > $specs
$cc -specs=$specs -mshared "$@"
;;
*) $cc "$@"
;;
esac

View File

@@ -0,0 +1,279 @@
: mvs.390 cc wrapper for Unix message and exit code semantics : 2012-01-20 :
HOSTTYPE=mvs.390
case " $* " in
*" -dumpmachine "*) echo $HOSTTYPE; exit ;;
esac
ar=ar
cc=/bin/c89
CC=/bin/c++
ccflags="-D_ALL_SOURCE -Wc,dll"
objmax=60
tmpfiles=
unbotch=
# -n as *first* arg shows but does not do
# -Wc,exportall => -Wl,dll
# -Bdynamic => .c,.o dynamic
# -Bstatic => .c,.o static
# *.C => cc=$CC
# *.cpp => cc=$CC
# *.cxx => cc=$CC
# no optimization until the optimizer is fixed:
# -O dropped (no optimization)
# -0 dropped (no optimization)
# -1 -O (default level 1 optimization)
# -2 -2 (maximal level 2 optimization)
let argc=0 cmp=0 dll=0 libc=0 dynamic=1 dynamic_objc=0 static_objc=0 relc=0 botched=0
case $1 in
-n) exec=print
shift
;;
*) exec=
;;
esac
export _CC_ACCEPTABLE_RC=1
export _C89_ACCEPTABLE_RC=$_CC_ACCEPTABLE_RC
export _CXX_ACCEPTABLE_RC=$_CC_ACCEPTABLE_RC
case " $* " in
*.C" "*)let dll=2
cc=$CC
export _CXXSUFFIX=C
;;
*.cpp" "*)let dll=2
cc=$CC
export _CXXSUFFIX=cpp
;;
*.cxx" "*)let dll=2
cc=$CC
export _CXXSUFFIX=cxx
;;
esac
exe=
xxx=
while :
do case $# in
0) break ;;
esac
arg=$1
case $arg in
-1) arg=-O
;;
-Bdynamic)
let dynamic=1
;;
-Bstatic)
let dynamic=0
;;
-c) let cmp=1
;;
-D_ALL_SOURCE|-D_ALL_SOURCE=*)
arg=
;;
-D*[\ \(\)]*)
arg=${arg#-D}
botch_macro[botched]=${arg%%=*}
botch_value[botched]=${arg#*=}
let botched=botched+1
arg=
;;
-o) argv[argc]=$arg
let argc=argc+1
shift
arg=$1
exe=$arg
rm -f "$exe"
;;
-[O0]) arg=
;;
-Wc,dll)arg=
;;
-Wc,exportall)
let dll=1
;;
-Wl,dll)arg=
let dll=1
;;
*.c) if [[ $botched != 0 ]]
then src=$arg
arg=${arg##*/}
unbotch="$unbotch ${arg%.c}.o"
arg=__$arg
tmpfiles="$tmpfiles $arg"
{
while [[ $botched != 0 ]]
do let botched=botched-1
print -r -- "#define ${botch_macro[botched]} ${botch_value[botched]}"
done
cat $src
} > $arg
fi
;;
*.o) if test 0 != $dynamic
then let dynamic_objc=dynamic_objc+1
else let static_objc=static_objc+1
fi
;;
*.x) a=${arg%.x}.a
if test -f $a
then argv[argc]=$a
let argc=argc+1
xxx=-Wl,dll
case $a in
ast.a|*/ast.a)
cc="$CC -u_ast_init"
;;
esac
fi
;;
esac
case $arg in
?*) argv[argc]=$arg
let argc=argc+1
;;
esac
shift
done
tmp=/tmp/cc.${USER:-$LOGNAME}.$$.err
tmpfiles="$tmp $tmpfiles"
# if any dll .o's are in .a then a .x gets generated
# but the native cc doesn't jcl for the .x
# -Wl,dll does that, so we nuke the .x and keep the exe
test 0 != $dll && xxx=
case $xxx in
?*) case $exe in
?*) a=${exe##*/}
a=${a%.*}
case $exe in
*/*) tmpfiles="$tmpfiles ${exe%/*}/${a}.x" ;;
*) tmpfiles="$tmpfiles ${a}.x" ;;
esac
;;
esac
;;
esac
if test 0 != $dll
then if test 0 != $cmp
then xxx="-D_SHARE_EXT_VARS $xxx"
else xxx="-Wl,dll $xxx"
fi
fi
set -- $xxx "${argv[@]}"
# can't handle more than objmax .o's
# -r into intermediates doesn't work, but the cat trick does
# also, the runtime dll file must be executable but cc -Wl,dll forgets
if test 0 != $dll -a \( $dynamic_objc -ge $objmax -o 0 != $static_objc \)
then unset argv
argc=0 libc=0 dynamic=1 dynamic_objc=0 static_objc=0 endc=0
while :
do case $# in
0) break ;;
esac
case $1 in
-Bdynamic)
let dynamic=1
;;
-Bstatic)
let dynamic=0
;;
*.o) if test 0 != $dynamic
then dynamic_objv[dynamic_objc]=$1
let dynamic_objc=dynamic_objc+1
else static_objv[static_objc]=$1
let static_objc=static_objc+1
fi
;;
-l*) libv[libc]=$1
let libc=libc+1
;;
-o) argv[argc]=$1
let argc=argc+1
shift
argv[argc]=$1
let argc=argc+1
exe=$1
;;
*) argv[argc]=$1
let argc=argc+1
;;
esac
shift
done
if test 0 != $static_objc
then case $exe in
?*) $exec $ar cr ${exe%.*}.a "${static_objv[@]}" ;;
esac
fi
if test 0 != $dynamic_objc
then cat=0.0.o
tmpfiles="$tmpfiles $cat"
cat "${dynamic_objv[@]}" > $cat || exit
else cat=
fi
set -- "${argv[@]}" $cat "${libv[@]}"
fi
# grep through the warning/error messages to get the true exit code
# some annoying messages are dropped while we're at it
trap 'rm -f $tmpfiles' 0 1 2 15
$exec $cc $ccflags "$@" 2> $tmp
code=$?
for i in $unbotch
do test -f __$i && mv __$i $i
done
typeset -l lc
while :
do if read line
then lc=$line
case $lc in
*'#include file'*'not found'*)
code=1
;;
*'#pragma ignored'*)
continue
;;
*'definition side file is not defined'*)
continue
;;
*'step ended with return code 4'*)
code=0
continue
;;
*'step ended with return code'*)
code=1
continue
;;
*'try again'*)
code=1
continue
;;
*'unknown preprocessing directive'*)
code=1
case $lc in
'warning '*)
set -- $line
shift
line=$*
;;
esac
;;
*'unresolved writable static references are detected'*)
test 0 != $dll && continue
;;
esac
else case $code:$exe in
0:?*) $exec chmod +x $exe ;;
esac
exit $code
fi
echo "$line" >&2
done < $tmp

View File

@@ -0,0 +1,158 @@
: next.i386 cc wrapper for Unix message and exit code semantics : 1995-05-09 :
HOSTTYPE=next.i386
case " $* " in
*" -dumpmachine "*) echo $HOSTTYPE; exit ;;
esac
# 1995-05-09 -lposix termios.o waitpid.o setpgid.o *do* work
# 1994-11-04 -posix has old redirection hole bug
# -D_POSIX_SOURCE requires <sys/dirent.h> manual fixes
# libexpr/exeval.c bombs -O, no -O ok
command=cc
cc="/bin/cc -D_POSIX_SOURCE"
nooptimize="exeval"
# first check $INSTALLROOT/botch
case $INSTALLROOT in
"") echo "$command: INSTALLROOT: must be defined and exported" >&2; exit 1 ;;
esac
if test ! -d $INSTALLROOT/botch -a -dryrun != "$1"
then if mkdir $INSTALLROOT/botch
then : ok to initialize
else echo "$command: $INSTALLROOT/botch must be initialized by the owner of $INSTALLROOT" 2>&1
exit 1
fi
(
cd $INSTALLROOT/botch
dir=.
for i in lib . include sys
do case $i in
.) dir=.
;;
*) case $i in
/*) dir=$i ;;
*) dir=$dir/$i ;;
esac
test -d $dir || mkdir $dir
;;
esac
done
if test ! -f include/sys/dirent.h
then echo "#include <dirent.h>" > tmp.c
header=`$cc -E tmp.c | sed -e '/^#[ ]*1[ ].*\/sys\/dirent\.h"/!d' -e 's/.*"\(.*\)".*/\1/'`
sed -e 's/[ ]off_t[ ][ ]*d_off[ ]*;//' $header > include/sys/dirent.h
fi
if test ! -f lib/libbotch.a
then lipo /usr/lib/libposix.a -thin i386 -output tmp.a
ar x tmp.a termios.o waitpid.o setpgid.o
ar cr lib/libbotch.a *.o
ranlib lib/libbotch.a
fi
rm -f *.[aco]
)
fi
# now slip in our args
case $nooptimize in
"") nooptimize=.
;;
*) optimize=
for arg in $nooptimize
do case $optimize in
?*) optimize="$optimize|" ;;
esac
optimize="$optimize$arg.[ci]|*/$arg.[ci]"
done
nooptimize=$optimize
;;
esac
set . "$@" .
noexec=
library=
local=
optimize=
verbose=
while :
do shift
arg=$1
shift
case $arg in
.) break
;;
-[cES]) library=1
;;
-O) optimize=1
;;
-v) verbose=1
;;
-dryrun)noexec=1
verbose=1
;;
-I-) case $local in
"") local=1
set . "$@" -I$INSTALLROOT/botch/include -I- -I$INSTALLROOT/botch/include
;;
*) set . "$@" -I- -I$INSTALLROOT/botch/include
;;
esac
continue
;;
-I*|*.[cChHiI]|*.[cChHiI][pPxX][pPxX])
case $optimize in
1) eval "
case \$arg in
$nooptimize)
optimize=0
;;
esac
"
;;
esac
case $local in
"") local=1
set . "$@" -I$INSTALLROOT/botch/include "$arg"
continue
;;
esac
;;
-last|*/libast.a)
case $library in
"") library=1
set . "$@" $INSTALLROOT/botch/lib/libbotch.a "$arg" $INSTALLROOT/botch/lib/libbotch.a
continue
;;
esac
;;
esac
set . "$@" "$arg"
done
case $library in
"") set . "$@" $INSTALLROOT/botch/lib/libbotch.a
shift
;;
esac
case $optimize in
0) set . "$@" .
while :
do shift
arg=$1
shift
case $arg in
.) break ;;
-O) set . "$@" ;;
*) set . "$@" "$arg" ;;
esac
done
;;
esac
case $verbose in
?*) echo $cc "$@" ;;
esac
case $noexec in
"") $cc "$@" ;;
esac

View File

@@ -0,0 +1,9 @@
: next.m68k cc wrapper that enables POSIX : 2000-12-15 :
HOSTTYPE=next.m68k
case " $* " in
*" -dumpmachine "*) echo $HOSTTYPE; exit ;;
esac
/bin/cc -posix -Xlinker -m "$@"

View File

@@ -0,0 +1,9 @@
: osf.alpha cc wrapper with reasonable namespace defaults : 1998-02-04 :
HOSTTYPE=osf.alpha
case " $* " in
*" -dumpmachine "*) echo $HOSTTYPE; exit ;;
esac
/usr/bin/cc -std -Dnoshare=_noshare_ -Dreadonly=_readonly_ "$@"

View File

@@ -0,0 +1,26 @@
: linux.pentium4 gcc wrapper : 2005-10-24 :
HOSTTYPE=linux.pentium4
case " $* " in
*" -dumpmachine "*) echo $HOSTTYPE; exit ;;
esac
case " $* " in
*" -O "*)
set -A argv -- "$@"
set -A nargv
integer i j
for ((i = j = 0; i < ${#argv[@]}; i++))
do if [[ ${argv[i]} == -O ]]
then nargv[j++]=-O3
nargv[j++]=-march=pentium4
else nargv[j++]=${argv[i]}
fi
done
gcc "${nargv[@]}"
exit
;;
esac
gcc "$@"

View File

@@ -0,0 +1,9 @@
: sco.i386 cc wrapper with reasonable binary and namespace : 1998-02-04 :
HOSTTYPE=sco.i386
case " $* " in
*" -dumpmachine "*) echo $HOSTTYPE; exit ;;
esac
/bin/cc -b elf -D_SVID3 "$@"

View File

@@ -0,0 +1,68 @@
: sgi.mips2 cc wrapper that generates MIPS II binaries : 2006-02-14 :
HOSTTYPE=sgi.mips2
case " $* " in
*" -dumpmachine "*) echo $HOSTTYPE; exit ;;
esac
cc=/usr/bin/cc
debug=
dynamic=-G0
flags=-OPT:Olimit=0
ignore=1685,733,1048,1155,1171,1184,1209,1343,3169,3170,3433
ldignore=15,84,85,13
optimize=
case $_AST_cc_OPTIONS in
?*) eval $_AST_cc_OPTIONS ;;
esac
case $ignore in
?*) ignore="-woff $ignore" ;;
esac
case $ldignore in
?*) ifs=$IFS
IFS=,
v=$ldignore
ldignore=
for i in $v
do ldignore="$ldignore -Wl,-woff,$i"
done
IFS=$ifs
;;
esac
case $debug in
?*) integer n=0
for i
do case $i in
-g*) case $debug in
-) continue ;;
esac
i=$debug
;;
esac
a[n++]=$i
done
set -- ${a[@]}
;;
esac
case $optimize in
?*) integer n=0
for i
do case $i in
-O*) case $optimize in
-) continue ;;
esac
i=$optimize
;;
esac
a[n++]=$i
done
set -- ${a[@]}
;;
esac
if test -d /usr/lib32
then LD_LIBRARYN32_PATH=/lib32 $cc -32 -mips2 $flags $dynamic $ldignore $ignore "$@"
else $cc -mips2 $flags $ignore "$@"
fi

View File

@@ -0,0 +1,110 @@
: sgi.mips3 cc wrapper that generates MIPS III binaries : 2007-04-27 :
HOSTTYPE=sgi.mips3
case " $* " in
*" -dumpmachine "*) echo $HOSTTYPE; exit ;;
esac
# ld:
# 15
# 84
# 85
# 134
# cc:
# 1685 (first!!) Invalid error number: X.
# 1035 cpp #error -- 0 exit status by default - botch botch botch
# 1048
# 1155
# 1171 The indicated expression has no effect.
# 1184 "=" is used where where "==" may have been intended.
# 1209 The controlling expression is constant.
# 1343
# 3169 X not marked as intrinsic because it is not yet declared
# 3170 X not marked as intrinsic because it is not yet declared
# 3421 expecting function name #pragma intrinsic (X)
# 3433 X not marked as intrinsic because it is not yet declared
# 3434 X not marked as intrinsic because it is not yet declared
cc=/usr/bin/cc
debug=
dynamic=-G0
flags=-OPT:Olimit=0
fatal=1035
ignore=1685,733,1048,1155,1171,1184,1209,1343,3169,3170,3421,3433,3434
ldignore=15,84,85,13
optimize=
case $_AST_cc_OPTIONS in
?*) eval $_AST_cc_OPTIONS ;;
esac
case $fatal in
?*) fatal="-diag_error $fatal" ;;
esac
case $ignore in
?*) ignore="-woff $ignore" ;;
esac
case $ldignore in
?*) ifs=$IFS
IFS=,
v=$ldignore
ldignore=
for i in $v
do ldignore="$ldignore -Wl,-woff,$i"
done
IFS=$ifs
;;
esac
case $debug in
?*) integer n=0
for i
do case $i in
-g*) case $debug in
-) continue ;;
esac
i=$debug
;;
esac
a[n++]=$i
done
set -- ${a[@]}
;;
esac
case $optimize in
?*) integer n=0
for i
do case $i in
-O*) case $optimize in
-) continue ;;
esac
i=$optimize
;;
esac
a[n++]=$i
done
set -- ${a[@]}
;;
esac
case $1 in
-mips2) if test -d /usr/lib32
then LD_LIBRARYN32_PATH=/lib32 $cc -32 -mips2 $flags $dynamic $ldignore $ignore "$@"
else $cc -mips2 $flags $ignore "$@"
fi
;;
-mips4) case " $* " in
*" -ldl "*)
integer n=0
for i
do case $i in
-ldl) ;;
*) a[n++]=$i ;;
esac
done
set -- ${a[@]}
esac
$cc -64 -mips4 $flags $dynamic $fatal $ldignore $ignore "$@"
;;
*) $cc -n32 -mips3 $flags $dynamic $fatal $ldignore $ignore "$@"
;;
esac

View File

@@ -0,0 +1,65 @@
: sgi.mips3-o32 cc wrapper that generates MIPS III O32 binaries : 2006-02-14 :
HOSTTYPE=sgi.mips3-o32
case " $* " in
*" -dumpmachine "*) echo $HOSTTYPE; exit ;;
esac
cc=/usr/bin/cc
debug=
dynamic=-G0
flags=
ignore=1685,733,1048,1155,1171,1184,1209,1343,3169,3170,3433
ldignore=15,84,85,13
optimize=
case $_AST_cc_OPTIONS in
?*) eval $_AST_cc_OPTIONS ;;
esac
case $ignore in
?*) ignore="-woff $ignore" ;;
esac
case $ldignore in
?*) ifs=$IFS
IFS=,
v=$ldignore
ldignore=
for i in $v
do ldignore="$ldignore -Wl,-woff,$i"
done
IFS=$ifs
;;
esac
case $debug in
?*) integer n=0
for i
do case $i in
-g*) case $debug in
-) continue ;;
esac
i=$debug
;;
esac
a[n++]=$i
done
set -- ${a[@]}
;;
esac
case $optimize in
?*) integer n=0
for i
do case $i in
-O*) case $optimize in
-) continue ;;
esac
i=$optimize
;;
esac
a[n++]=$i
done
set -- ${a[@]}
;;
esac
$cc -o32 -mips3 $flags $dynamic $ldignore $ignore "$@"

View File

@@ -0,0 +1,90 @@
: sgi.mips4 cc wrapper that generates MIPS IV binaries : 2007-04-27 :
HOSTTYPE=sgi.mips4
case " $* " in
*" -dumpmachine "*) echo $HOSTTYPE; exit ;;
esac
cc=/usr/bin/cc
debug=
dynamic=-G0
flags=-OPT:Olimit=0
fatal=1035
ignore=1685,733,1048,1155,1171,1184,1209,1343,3169,3170,3433
ldignore=15,84,85,13
optimize=
case $_AST_cc_OPTIONS in
?*) eval $_AST_cc_OPTIONS ;;
esac
case $fatal in
?*) fatal="-diag_error $fatal" ;;
esac
case $ignore in
?*) ignore="-woff $ignore" ;;
esac
case $ldignore in
?*) ifs=$IFS
IFS=,
v=$ldignore
ldignore=
for i in $v
do ldignore="$ldignore -Wl,-woff,$i"
done
IFS=$ifs
;;
esac
case $debug in
?*) integer n=0
for i
do case $i in
-g*) case $debug in
-) continue ;;
esac
i=$debug
;;
esac
a[n++]=$i
done
set -- ${a[@]}
;;
esac
case $optimize in
?*) integer n=0
for i
do case $i in
-O*) case $optimize in
-) continue ;;
esac
i=$optimize
;;
esac
a[n++]=$i
done
set -- ${a[@]}
;;
esac
case $1 in
-mips2) if test -d /usr/lib32
then LD_LIBRARYN32_PATH=/lib32 $cc -32 -mips2 $flags $dynamic $ldignore $ignore "$@"
else $cc -mips2 $flags $ignore "$@"
fi
;;
-mips3) $cc -n32 -mips3 $flags $dynamic $fatal $ldignore $ignore "$@"
;;
*) case " $* " in
*" -ldl "*)
integer n=0
for i
do case $i in
-ldl) ;;
*) a[n++]=$i ;;
esac
done
set -- ${a[@]}
esac
$cc -64 -mips4 $flags $dynamic $fatal $ldignore $ignore "$@"
;;
esac

View File

@@ -0,0 +1,65 @@
: sgi.mips4-n32 cc wrapper that generates MIPS IV N32 binaries : 2006-02-14 :
HOSTTYPE=sgi.mips4-n32
case " $* " in
*" -dumpmachine "*) echo $HOSTTYPE; exit ;;
esac
cc=/usr/bin/cc
debug=
dynamic=-G0
flags=
ignore=1685,733,1048,1155,1171,1184,1209,1343,3169,3170,3433
ldignore=15,84,85,13
optimize=
case $_AST_cc_OPTIONS in
?*) eval $_AST_cc_OPTIONS ;;
esac
case $ignore in
?*) ignore="-woff $ignore" ;;
esac
case $ldignore in
?*) ifs=$IFS
IFS=,
v=$ldignore
ldignore=
for i in $v
do ldignore="$ldignore -Wl,-woff,$i"
done
IFS=$ifs
;;
esac
case $debug in
?*) integer n=0
for i
do case $i in
-g*) case $debug in
-) continue ;;
esac
i=$debug
;;
esac
a[n++]=$i
done
set -- ${a[@]}
;;
esac
case $optimize in
?*) integer n=0
for i
do case $i in
-O*) case $optimize in
-) continue ;;
esac
i=$optimize
;;
esac
a[n++]=$i
done
set -- ${a[@]}
;;
esac
$cc -n32 -mips4 $flags $dynamic $ldignore $ignore "$@"

View File

@@ -0,0 +1,35 @@
: -O* specialization cc wrapper : 2011-11-11 :
case " $* " in
*" -dumpmachine "*) echo $HOSTTYPE; exit ;;
esac
cc=cc
CCREPLACE='' # these (possibly empty) options replace -O*
CCALWAYS='' # these (possibly empty) options always set
case $CCREPLACE in
'') ;;
*) case " $* " in
*" -O"*)
set '' "$@" ''
shift
while :
do a=$1
shift
case $a in
'') break
;;
-O*) set '' "$@" $CCREPLACE
;;
*) set '' "$@" "$a"
;;
esac
shift
done
;;
esac
;;
esac
$cc $CCALWAYS "$@"

View File

@@ -0,0 +1,76 @@
: 3B1/PC7300 unix.mc68k cc wrapper for ANSI C : 2002-09-01 :
HOSTTYPE=unix.mc68k
case " $* " in
*" -dumpmachine "*) echo $HOSTTYPE; exit ;;
esac
# /bin/cc predates ANSI C; use gcc
# some headers depend on SYSTEM5 or mc68k being defined
# headers for Ethernet software are under /usr/ethernet/include
# both /usr/lib/libnet.a and /usr/lib/libcurses.a define select()
# -lcurses uses a version of select for napms(), but that
# implementation always returns an error if given file
# descriptors to watch
# the one in -lnet must be used if fds (instead of or in addition to
# a timeout) are of interest therefore, -lnet should be
# specified before -lcurses
# rename(old, new) in /usr/lib/libnet.a fails if new exists
# (permitted by ANSI/ISO C-1990 7.9.4.2)
# gcc -fpic doesn't work as there's no _GLOBAL_OFFSET_TABLE symbol
cc="gcc"
exec=
show=:
inc=0
lib=0
set '' -DSYSTEM5 -Dmc68k "$@" ''
shift
while :
do a=$1
shift
case $a in
'') break
;;
-lcurses|libcurses.a|*/libcurses.a)
lib=1
set '' "$@" -lnet
shift
;;
-lnet|libnet.a|*/libnet.a)
lib=1
;;
-o) a=$1
shift
set '' "$@" -o
shift
;;
-fpic) continue
;;
-n) exec=:
continue
;;
-v) show=echo
continue
;;
-*) ;;
*) case $inc in
0) inc=1
set '' "$@" -I/usr/ethernet/include
shift
;;
esac
;;
esac
set '' "$@" "$a"
shift
done
case $lib in
0) set '' "$@" -lnet
shift
;;
esac
$show $cc "$@"
$exec $cc "$@"

View File

@@ -0,0 +1,9 @@
: unixware.i386 cc wrapper
HOSTTYPE=unixware.i386
case " $* " in
*" -dumpmachine "*) echo $HOSTTYPE; exit ;;
esac
/bin/cc -D_XOPEN_UNIX -D_XOPEN_SOURCE_EXTENDED "$@"

View File

@@ -0,0 +1,140 @@
########################################################################
# #
# This software is part of the ast package #
# Copyright (c) 1994-2011 AT&T Intellectual Property #
# Copyright (c) 2020-2022 Contributors to ksh 93u+m #
# and is licensed under the #
# Eclipse Public License, Version 2.0 #
# #
# A copy of the License is available at #
# https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html #
# (with md5 checksum 84283fa8859daf213bdda5a9f8d1be1d) #
# #
# Glenn Fowler <gsf@research.att.com> #
# Martijn Dekker <martijn@inlv.org> #
# #
########################################################################
: cross compiler a.out execution
(command set -o posix) 2>/dev/null && set -o posix
command=crossexec
tmp=/tmp/cross$$
case `(getopts '[-][123:xyz]' opt --xyz; echo 0$opt) 2>/dev/null` in
0123) ARGV0="-a $command"
USAGE=$'
[-?
@(#)$Id: crossexec (AT&T Labs Research) 2004-01-04 $
]
[-author?Glenn Fowler <gsf@research.att.com>]
[-copyright?Copyright (c) 1994-2012 AT&T Intellectual Property]
[-license?https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html]
[+NAME?crossexec - cross compiler a.out execution]
[+DESCRIPTION?\bcrossexec\b runs a cross-compiled \acommand\a in an environment
that supports a cross-compilation architecture different from the
current host. The cross environment is determined by \acrosstype\a,
usually a host type name produced by \bpackage\b(1). \acrosstype\a
is used to find an entry in \b$HOME/.crossexec\b that specifies
the cross compiler host and access details.]
[+?The exit status of \bcrossexec\b is the exit status of \acommand\a.]
[+CROSS ENVIRONMENT FILE?\b$HOME/.crossexec\b contains one line for each
supported \acrosstype\a. Each line contains 5 tab separated fields.
Field default values are specified as \b-\b. The fields are:]{
[+crosstype?The host type produced by \bpackage\b(1).]
[+host?The host name.]
[+user?The user name on \ahost\a. The default is the current user.]
[+dir?The directory to copy \acommand\a and execute it. The default
is the \auser\a \b$HOME\b on \ahost\a.]
[+shell?The command used to get shell access to \ahost\a. Currently
only \brsh\b and \bssh\b are supported.]
[+copy?The command used to copy \acommand\a to \ahost\a. Currently
only \brcp\b and \bscp\b are supported.]
}
[n:show?Show the underlying commands but do not execute.]
crosstype command [ option ... ] [ file ... ]
[+SEE ALSO?\brcp\b(1), \brsh\b(1), \bscp\b(1), \bssh\b(1)]
'
;;
*) ARGV0=""
USAGE="crosstype command [ option ... ] [ file ... ]"
;;
esac
usage()
{
OPTIND=0
getopts $ARGV0 "$USAGE" OPT '-?'
exit 2
}
exec=
# get the options and operands
while getopts $ARGV0 "$USAGE" OPT
do case $OPT in
n) exec=echo ;;
*) usage ;;
esac
done
shift $OPTIND-1
case $# in
[01]) usage ;;
esac
type=$1
shift
cmd=$1
shift
# get the host info
info=$HOME/.$command
if test ! -r $info
then echo "$command: $info: not found" >&2
exit 1
fi
ifs=${IFS-'
'}
while :
do IFS=' '
read hosttype hostname usr dir sh cp
code=$?
IFS=$ifs
case $code in
0) ;;
*) echo "$command: $type: unknown cross compiler host type" >&2
exit 1
;;
esac
case $hosttype in
$type) break ;;
esac
done < $info
# fill in the defaults
case $usr in
-) cpu= shu= ;;
*) cpu=${usr}@ shu="-l $usr" ;;
esac
case $dir in
-) dir= ;;
esac
case $sh in
''|-) sh=ssh ;;
esac
case $cp in
''|-) cp=scp ;;
scp) cp="$cp -q" ;;
esac
trap "rm -f $tmp" 0 1 2 3 15
$exec $cp $cmd $cpu$hostname:$dir </dev/null || exit 1
cmd=./${cmd##*/}
$exec $sh $shu $hostname "cd $dir; LD_LIBRARY_PATH=: $cmd $@ </dev/null 2>/dev/null; code=\$?; rm -f $cmd; echo $command: exit \$code >&2" </dev/null 2>$tmp
exit `sed -e '/^'$command': exit [0-9][0-9]*$/!d' -e 's/.* //' $tmp`

View File

@@ -0,0 +1,34 @@
/***********************************************************************
* *
* This software is part of the ast package *
* Copyright (c) 1994-2011 AT&T Intellectual Property *
* Copyright (c) 2020-2022 Contributors to ksh 93u+m *
* and is licensed under the *
* Eclipse Public License, Version 2.0 *
* *
* A copy of the License is available at *
* https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html *
* (with md5 checksum 84283fa8859daf213bdda5a9f8d1be1d) *
* *
* Glenn Fowler <gsf@research.att.com> *
* Martijn Dekker <martijn@inlv.org> *
* *
***********************************************************************/
/*
* small test for sleepycat dbm compatibility
*/
#define DB_DBM_HSEARCH 1
#if DB_DBM_HSEARCH
#include <db.h>
#endif
int
main()
{
DBM* dbm = 0;
dbm_close(dbm);
return 0;
}

View File

@@ -0,0 +1,30 @@
/***********************************************************************
* *
* This software is part of the ast package *
* Copyright (c) 1994-2011 AT&T Intellectual Property *
* Copyright (c) 2020-2022 Contributors to ksh 93u+m *
* and is licensed under the *
* Eclipse Public License, Version 2.0 *
* *
* A copy of the License is available at *
* https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html *
* (with md5 checksum 84283fa8859daf213bdda5a9f8d1be1d) *
* *
* Glenn Fowler <gsf@research.att.com> *
* Martijn Dekker <martijn@inlv.org> *
* *
***********************************************************************/
/*
* small test for -ldl
*/
#ifndef dlopen
#include <dlfcn.h>
#endif
int
main()
{
dlopen("libdl.so",0);
return 0;
}

View File

@@ -0,0 +1,186 @@
########################################################################
# #
# This software is part of the ast package #
# Copyright (c) 1994-2011 AT&T Intellectual Property #
# Copyright (c) 2020-2022 Contributors to ksh 93u+m #
# and is licensed under the #
# Eclipse Public License, Version 2.0 #
# #
# A copy of the License is available at #
# https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html #
# (with md5 checksum 84283fa8859daf213bdda5a9f8d1be1d) #
# #
# Glenn Fowler <gsf@research.att.com> #
# Martijn Dekker <martijn@inlv.org> #
# #
########################################################################
: wrapper for .exe challenged Win32 systems/commands
(command set -o posix) 2>/dev/null && set -o posix
command=execrate
bins=`
(
userPATH=$PATH
PATH=/run/current-system/sw/bin:/usr/xpg7/bin:/usr/xpg6/bin:/usr/xpg4/bin:/bin:/usr/bin:$PATH
getconf PATH 2>/dev/null && echo "$userPATH" || echo /bin:/usr/bin:/sbin:/usr/sbin:"$userPATH"
) | sed 's/:/ /g'
` || exit
case `(getopts '[-][123:xyz]' opt --xyz; echo 0$opt) 2>/dev/null` in
0123) ARGV0="-a $command"
USAGE=$'
[-?
@(#)$Id: execrate (AT&T Labs Research) 2002-02-02 $
]
[-author?Glenn Fowler <gsf@research.att.com>]
[-copyright?Copyright (c) 2002-2012 AT&T Intellectual Property]
[-license?https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html]
[+NAME?execrate - wrapper for .exe challenged commands]
[+DESCRIPTION?\bexecrate\b runs \acommand\a after checking the \afile\a
operands for standard semantics with respect to \bWin32\b \b.exe\b
suffix conventions. This command is only needed on \bWin32\b
systems that inconsistently handle \b.exe\b across library and
command interfaces. \acommand\a may be one of \bcat\b(1), \bchmod\b(1),
\bcmp\b(1), \bcp\b(1), \bln\b(1), \bmv\b(1), or \brm\b(1).
Only the 2 argument forms of \bcp\b, \bln\b and \bmv\b are handled.
Unsupported commands and commands requiring no change are
silently executed.]
[+?With no arguments \bexecrate\b exits with status 0 if the current system
is \b.exe\b challenged, 1 if the current system is normal.]
[n:show?Show the underlying commands but do not execute.]
command [ option ... ] file ...
[+SEE ALSO?\bwebster\b(1)]
'
usage()
{
OPTIND=0
getopts $ARGV0 "$USAGE" OPT '-?'
exit 2
}
exec=1
while getopts $ARGV0 "$USAGE" OPT
do case $OPT in
n) exec=0 ;;
*) usage ;;
esac
done
shift `expr $OPTIND - 1`
;;
*) usage()
{
echo "Usage: execrate [ -n ] [ command [ option ... ] file ... ]" >&2
exit 2
}
exec=1
while :
do case $1 in
-n) exec=0 ;;
-*) usage ;;
*) break ;;
esac
shift
done
;;
esac
case $# in
0) if test ! -x /bin/cat.exe
then exit 1 # normal
fi
if /bin/cat /bin/cat >/dev/null 2>&1
then exit 1 # normal
fi
exit 0 # challenged
;;
1) usage
;;
esac
case $1 in
*cat|*rm)
NUM=0
;;
*chgrp|*chmod)
NUM=1
;;
*cmp|*cp|*ln|*mv)
NUM=2
;;
*) case $exec in
0) echo "$@" ;;
*) "$@" ;;
esac
exit
;;
esac
CMD=$1
shift
case $CMD in
*/*) ;;
*) for d in $bins
do if test -x $d/$1 -o -x $d/$1.exe
then CMD=$d/$1
break
fi
done
;;
esac
while :
do case $1 in
-*) CMD="$CMD $1" ;;
*) break ;;
esac
shift
done
case $exec in
0) CMD="echo $CMD" ;;
esac
case $NUM:$# in
*:0) ;;
1:*) CMD="$CMD $1"
NUM=0
shift
;;
esac
case $NUM:$# in
0:*) status=0
for f
do if test "$f" -ef "$f".exe
then f=$f.exe
fi
$CMD "$f"
case $? in
0) ;;
*) status=$? ;;
esac
done
exit $status
;;
2:2) f=$1
case $f in
*.exe) ;;
*) if test "$f" -ef "$f".exe
then f=$f.exe
fi
;;
esac
case $f in
*.exe) if test -d "$2"
then t=$2/$f
else t=$2
fi
case $t in
*/*) b=`basename "$t"` ;;
*) b=$t ;;
esac
case $b in
*.*) $CMD "$f" "$t"; exit ;;
*) $CMD "$f" "$t".exe; exit ;;
esac
;;
esac
;;
esac
$CMD "$@"

View File

@@ -0,0 +1,101 @@
########################################################################
# #
# This software is part of the ast package #
# Copyright (c) 1994-2011 AT&T Intellectual Property #
# Copyright (c) 2020-2022 Contributors to ksh 93u+m #
# and is licensed under the #
# Eclipse Public License, Version 2.0 #
# #
# A copy of the License is available at #
# https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html #
# (with md5 checksum 84283fa8859daf213bdda5a9f8d1be1d) #
# #
# Glenn Fowler <gsf@research.att.com> #
# Martijn Dekker <martijn@inlv.org> #
# #
########################################################################
: convert command that operates on file args to pipeline filter
(command set -o posix) 2>/dev/null && set -o posix
command=filter
TMPDIR=${TMPDIR:-/tmp}
export TMPDIR
tmp=$TMPDIR/$command$$
suf=
case `(getopts '[-][123:xyz]' opt --xyz; echo 0$opt) 2>/dev/null` in
0123) ARGV0="-a $command"
USAGE=$'
[-?
@(#)$Id: filter (AT&T Labs Research) 2001-05-31 $
]
[-author?Glenn Fowler <gsf@research.att.com>]
[-copyright?Copyright (c) 1994-2012 AT&T Intellectual Property]
[-license?https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html]
[+NAME?filter - run a command in stdin/stdout mode]
[+DESCRIPTION?\bfilter\b runs \acommand\a in a mode that takes input from
the \afile\a operands, or from the standard input if no \afile\a
operands are specified, and writes the results to the standard output.
It can be used to run commands like \bsplit\b(1), that normally modify
\afile\a operands in-place, in pipelines. The \afile\a operands are
not modified; \acommand\a is run on copies in \b/tmp\b.]
command [ option ... ] [ file ... ]
[+SEE ALSO?\bstrip\b(1)]
'
;;
*) ARGV0=""
USAGE="command [ option ... ] [ file ... ]"
;;
esac
usage()
{
OPTIND=0
getopts $ARGV0 "$USAGE" OPT '-?'
exit 2
}
while getopts $ARGV0 "$USAGE" OPT
do case $OPT in
*) usage ;;
esac
done
shift `expr $OPTIND - 1`
case $# in
0) usage ;;
esac
cmd=$1
while :
do shift
case $# in
0) break ;;
esac
case $1 in
-*) cmd="$cmd $1" ;;
*) break ;;
esac
done
trap 'rm -f $tmp$suf' 0 1 2 3 15
case $# in
0) cat > $tmp
$cmd $tmp
;;
*) for file
do suf=${file##*/}
case $suf in
*.*) suf=.${suf#*.} ;;
*) suf= ;;
esac
cp $file $tmp$suf || exit 1
chmod u+rwx $tmp$suf || exit 1
$cmd $tmp$suf || exit 1
cat $tmp$suf
rm -f $tmp$suf
done
;;
esac

View File

@@ -0,0 +1,34 @@
/***********************************************************************
* *
* This software is part of the ast package *
* Copyright (c) 1994-2011 AT&T Intellectual Property *
* Copyright (c) 2020-2022 Contributors to ksh 93u+m *
* and is licensed under the *
* Eclipse Public License, Version 2.0 *
* *
* A copy of the License is available at *
* https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html *
* (with md5 checksum 84283fa8859daf213bdda5a9f8d1be1d) *
* *
* Glenn Fowler <gsf@research.att.com> *
* Martijn Dekker <martijn@inlv.org> *
* *
***********************************************************************/
/*
* small test for -lgdbm
*/
#define _hdr_gdbm_ndbm 1
#if _hdr_gdbm_ndbm
#include <gdbm/ndbm.h>
#endif
int
main()
{
DBM* dbm = 0;
dbm_close(dbm);
return 0;
}

View File

@@ -0,0 +1,34 @@
/***********************************************************************
* *
* This software is part of the ast package *
* Copyright (c) 1994-2011 AT&T Intellectual Property *
* Copyright (c) 2020-2022 Contributors to ksh 93u+m *
* and is licensed under the *
* Eclipse Public License, Version 2.0 *
* *
* A copy of the License is available at *
* https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html *
* (with md5 checksum 84283fa8859daf213bdda5a9f8d1be1d) *
* *
* Glenn Fowler <gsf@research.att.com> *
* Martijn Dekker <martijn@inlv.org> *
* *
***********************************************************************/
/*
* small test for -lgdbm
*/
#define _hdr_gdbm_ndbm 1
#if _hdr_gdbm_ndbm
#include <gdbm-ndbm.h>
#endif
int
main()
{
DBM* dbm = 0;
dbm_close(dbm);
return 0;
}

View File

@@ -0,0 +1,34 @@
/***********************************************************************
* *
* This software is part of the ast package *
* Copyright (c) 1994-2011 AT&T Intellectual Property *
* Copyright (c) 2020-2022 Contributors to ksh 93u+m *
* and is licensed under the *
* Eclipse Public License, Version 2.0 *
* *
* A copy of the License is available at *
* https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html *
* (with md5 checksum 84283fa8859daf213bdda5a9f8d1be1d) *
* *
* Glenn Fowler <gsf@research.att.com> *
* Martijn Dekker <martijn@inlv.org> *
* *
***********************************************************************/
/*
* small test for -lgdbm
*/
#define _hdr_ndbm 1
#if _hdr_ndbm
#include <ndbm.h>
#endif
int
main()
{
DBM* dbm = 0;
dbm_close(dbm);
return 0;
}

View File

@@ -0,0 +1,20 @@
/***********************************************************************
* *
* This software is part of the ast package *
* Copyright (c) 1994-2011 AT&T Intellectual Property *
* Copyright (c) 2020-2022 Contributors to ksh 93u+m *
* and is licensed under the *
* Eclipse Public License, Version 2.0 *
* *
* A copy of the License is available at *
* https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html *
* (with md5 checksum 84283fa8859daf213bdda5a9f8d1be1d) *
* *
* Glenn Fowler <gsf@research.att.com> *
* Martijn Dekker <martijn@inlv.org> *
* *
***********************************************************************/
#ifndef printf
#include <stdio.h>
#endif
int main() { int new = 0; printf("hello world\n"); return new;}

View File

@@ -0,0 +1,6 @@
hp.pa hostname 9000/730 hp9000s700 HP-UX hostname A.09.01 A
linux-aout.i386 hostname i586 i386 linux hostname 1.1.59 #1
sgi.mips2 hostname.domain IP22 mips IRIX hostname 5.2 02282016
osf.alpha hostname.domain alpha alpha OSF1 hostname.domain V3.2 62
sun4 hostname.domain sun4 sparc SunOS hostname.domain 4.1.1 1 sun4c
sol.sun4 hostname.domain sun4 sparc SunOS hostname.domain 5.4 Generic_101945-13

View File

@@ -0,0 +1,26 @@
/***********************************************************************
* *
* This software is part of the ast package *
* Copyright (c) 1994-2011 AT&T Intellectual Property *
* Copyright (c) 2020-2022 Contributors to ksh 93u+m *
* and is licensed under the *
* Eclipse Public License, Version 2.0 *
* *
* A copy of the License is available at *
* https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html *
* (with md5 checksum 84283fa8859daf213bdda5a9f8d1be1d) *
* *
* Glenn Fowler <gsf@research.att.com> *
* Martijn Dekker <martijn@inlv.org> *
* *
***********************************************************************/
#ifndef iconv
#include <iconv.h>
#endif
int
main()
{
iconv(0, 0, 0, 0, 0);
return 0;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,33 @@
########################################################################
# #
# This software is part of the ast package #
# Copyright (c) 1994-2011 AT&T Intellectual Property #
# Copyright (c) 2020-2022 Contributors to ksh 93u+m #
# and is licensed under the #
# Eclipse Public License, Version 2.0 #
# #
# A copy of the License is available at #
# https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html #
# (with md5 checksum 84283fa8859daf213bdda5a9f8d1be1d) #
# #
# Glenn Fowler <gsf@research.att.com> #
# Martijn Dekker <martijn@inlv.org> #
# #
########################################################################
# non-ksh script for the nmake ignore prefix
# @(#)ignore (ksh 93u+m) 2021-12-31
while :
do case $# in
0) exit 0 ;;
esac
case $1 in
*=*) export "$1"
shift
;;
*) break
;;
esac
done
"$@"
exit 0

View File

@@ -0,0 +1,26 @@
/***********************************************************************
* *
* This software is part of the ast package *
* Copyright (c) 1994-2011 AT&T Intellectual Property *
* Copyright (c) 2020-2022 Contributors to ksh 93u+m *
* and is licensed under the *
* Eclipse Public License, Version 2.0 *
* *
* A copy of the License is available at *
* https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html *
* (with md5 checksum 84283fa8859daf213bdda5a9f8d1be1d) *
* *
* Glenn Fowler <gsf@research.att.com> *
* Martijn Dekker <martijn@inlv.org> *
* *
***********************************************************************/
#ifndef gettext
#include <libintl.h>
#endif
int
main()
{
gettext(0);
return 0;
}

View File

@@ -0,0 +1,5 @@
: hp.pa ld wrapper for reasonable warning defaults
# @(#)ld.hp.pa (AT&T Labs Research) 1998-01-23
/bin/ld +s +vnocompatwarnings "$@"

View File

@@ -0,0 +1,22 @@
#!/bin/env sh
: cygwin.i386 ldd -- how many ways does this confirm the Windows bias?
for f
do case $f in
*.exe) ;;
*) f=$f.exe ;;
esac
p=$(type $f)
case $p in
*" not found"*)
;;
*) p=${p##* }
case $p in
?*) f=$p ;;
esac
;;
esac
cygcheck $(cygpath -aw $f) |
for w in $(sed -e 's/^[[:space:]]*//' -e '/^$/d' -e '/^Use /d')
do cygpath -u "$w"
done
done

View File

@@ -0,0 +1,2 @@
: Mac OS X ldd
otool -L "$@"

View File

@@ -0,0 +1,21 @@
: hp.pa ldd
while :
do case $# in
0) break ;;
esac
case $1 in
-*|+*) ;;
*) break ;;
esac
shift
done
trap ':' 15
for cmd
do case $# in
1) ;;
*) echo $cmd: ;;
esac
_HP_DLDOPTS=-ldd "$cmd" < /dev/null 2> /dev/null | sort -u
# chatr "$cmd" |
# sed -e '/^[ ]*dynamic[ ][ ]*/!d' -e 's// /'
done

View File

@@ -0,0 +1,16 @@
: ibm.risc ldd
case $# in
1) header=0 ;;
*) header=1 ;;
esac
for file
do case $header in
1) echo "$file:"
header=2
;;
2) echo
echo "$file:"
;;
esac
dump -H "$file" | sed '1,/\*\*\*Import/d'
done

View File

@@ -0,0 +1 @@
elflook -L "$@" | sed -e '/^NEEDED:/!d' -e 's/.*: *//'

View File

@@ -0,0 +1,18 @@
: mvs.390 ldd
case $# in
1) header=0 ;;
*) header=1 ;;
esac
for file
do case $header in
1) echo "$file:"
header=2
;;
2) echo
echo "$file:"
;;
esac
strings $file |
sed -e '/\<[[:lower:]][[:alnum:]]*\.dll\>/!d' -e 's/^/ /' |
sort -u
done

View File

@@ -0,0 +1,2 @@
: sgi.mips ldd
odump -Dl "$@"

View File

@@ -0,0 +1,31 @@
/***********************************************************************
* *
* This software is part of the ast package *
* Copyright (c) 1994-2011 AT&T Intellectual Property *
* Copyright (c) 2020-2022 Contributors to ksh 93u+m *
* and is licensed under the *
* Eclipse Public License, Version 2.0 *
* *
* A copy of the License is available at *
* https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html *
* (with md5 checksum 84283fa8859daf213bdda5a9f8d1be1d) *
* *
* Glenn Fowler <gsf@research.att.com> *
* Martijn Dekker <martijn@inlv.org> *
* *
***********************************************************************/
/*
* -lm test #1
*/
#ifndef sin
#include <math.h>
#endif
int
main()
{
sin(0.0);
fmod(100.234, 11.0);
return 0;
}

View File

@@ -0,0 +1,33 @@
/***********************************************************************
* *
* This software is part of the ast package *
* Copyright (c) 1994-2011 AT&T Intellectual Property *
* Copyright (c) 2020-2022 Contributors to ksh 93u+m *
* and is licensed under the *
* Eclipse Public License, Version 2.0 *
* *
* A copy of the License is available at *
* https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html *
* (with md5 checksum 84283fa8859daf213bdda5a9f8d1be1d) *
* *
* Glenn Fowler <gsf@research.att.com> *
* Martijn Dekker <martijn@inlv.org> *
* *
***********************************************************************/
/*
* -lm test #2
*/
#include <math.h>
int
main()
{
double value = 0;
int exp = 0;
int r = 0;
r |= ldexp(value, exp) != 0;
r |= frexp(value, &exp) != 0;
return r;
}

View File

@@ -0,0 +1,33 @@
/***********************************************************************
* *
* This software is part of the ast package *
* Copyright (c) 1994-2011 AT&T Intellectual Property *
* Copyright (c) 2020-2022 Contributors to ksh 93u+m *
* and is licensed under the *
* Eclipse Public License, Version 2.0 *
* *
* A copy of the License is available at *
* https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html *
* (with md5 checksum 84283fa8859daf213bdda5a9f8d1be1d) *
* *
* Glenn Fowler <gsf@research.att.com> *
* Martijn Dekker <martijn@inlv.org> *
* *
***********************************************************************/
/*
* -lm test #3
*/
#include <math.h>
int
main()
{
long double value = 0;
int exp = 0;
int r = 0;
r |= ldexpl(value, exp) != 0;
r |= frexpl(value, &exp) != 0;
return r;
}

View File

@@ -0,0 +1,29 @@
/***********************************************************************
* *
* This software is part of the ast package *
* Copyright (c) 1994-2011 AT&T Intellectual Property *
* Copyright (c) 2020-2022 Contributors to ksh 93u+m *
* and is licensed under the *
* Eclipse Public License, Version 2.0 *
* *
* A copy of the License is available at *
* https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html *
* (with md5 checksum 84283fa8859daf213bdda5a9f8d1be1d) *
* *
* Glenn Fowler <gsf@research.att.com> *
* Martijn Dekker <martijn@inlv.org> *
* *
***********************************************************************/
/*
* -lm test #4
*/
#include <math.h>
int
main()
{
double value = 0;
return isnan(value);
}

View File

@@ -0,0 +1,29 @@
/***********************************************************************
* *
* This software is part of the ast package *
* Copyright (c) 1994-2011 AT&T Intellectual Property *
* Copyright (c) 2020-2022 Contributors to ksh 93u+m *
* and is licensed under the *
* Eclipse Public License, Version 2.0 *
* *
* A copy of the License is available at *
* https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html *
* (with md5 checksum 84283fa8859daf213bdda5a9f8d1be1d) *
* *
* Glenn Fowler <gsf@research.att.com> *
* Martijn Dekker <martijn@inlv.org> *
* *
***********************************************************************/
/*
* -lm test #5
*/
#include <math.h>
int
main()
{
long double value = 0;
return isnanl(value);
}

View File

@@ -0,0 +1,31 @@
/***********************************************************************
* *
* This software is part of the ast package *
* Copyright (c) 1994-2011 AT&T Intellectual Property *
* Copyright (c) 2020-2022 Contributors to ksh 93u+m *
* and is licensed under the *
* Eclipse Public License, Version 2.0 *
* *
* A copy of the License is available at *
* https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html *
* (with md5 checksum 84283fa8859daf213bdda5a9f8d1be1d) *
* *
* Glenn Fowler <gsf@research.att.com> *
* Martijn Dekker <martijn@inlv.org> *
* *
***********************************************************************/
/*
* -lm test #6
*/
#define _ISOC99_SOURCE 1
#include <math.h>
int
main()
{
double value = -0.0;
return !signbit(value);
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,40 @@
NOTE regression tests for the mamake command
UNIT mamake
TEST macros
DATA Mamfile <<'!'
info mam static 00000 1994-07-17 make (AT&T Research) 5.3 2009-05-05
setv DEFINED defined
setv EMPTY
make all
exec - echo DEFINED ${DEFINED}
exec - echo DEFINED:VALUE ${DEFINED:VALUE}
exec - echo DEFINED:-VALUE ${DEFINED:-VALUE}
exec - echo DEFINED=VALUE ${DEFINED=VALUE}
exec - echo DEFINED[VALUE] ${DEFINED[VALUE]}
exec - echo DEFINED.COMPONENT ${DEFINED.COMPONENT}
exec - echo DEFINED.COMPONENT[VALUE] ${DEFINED.COMPONENT[VALUE]}
exec - echo EMPTY ${EMPTY}
exec - echo EMPTY:VALUE ${EMPTY:VALUE}
exec - echo EMPTY:-VALUE ${EMPTY:-VALUE}
exec - echo EMPTY=VALUE ${EMPTY=VALUE}
exec - echo EMPTY[VALUE] ${EMPTY[VALUE]}
exec - echo EMPTY.COMPONENT ${EMPTY.COMPONENT}
exec - echo EMPTY.COMPONENT[VALUE] ${EMPTY.COMPONENT[VALUE]}
exec - echo __NoT_DeFiNeD__ ${__NoT_DeFiNeD__}
exec - echo __NoT_DeFiNeD__:VALUE ${__NoT_DeFiNeD__:VALUE}
exec - echo __NoT_DeFiNeD__:-VALUE ${__NoT_DeFiNeD__:-VALUE}
exec - echo __NoT_DeFiNeD__=VALUE ${__NoT_DeFiNeD__=VALUE}
exec - echo __NoT_DeFiNeD__[VALUE] ${__NoT_DeFiNeD__[VALUE]}
exec - echo __NoT_DeFiNeD__.COMPONENT ${__NoT_DeFiNeD__.COMPONENT}
exec - echo __NoT_DeFiNeD__.COMPONENT[VALUE] ${__NoT_DeFiNeD__.COMPONENT[VALUE]}
done all generated virtual
!
EXEC -n

View File

@@ -0,0 +1,63 @@
# : : generated from mamake.rt by mktest : : #
# regression tests for the mamake command
UNIT mamake
TEST 01 macros
EXEC -n
INPUT -n -
INPUT Mamfile $'info mam static 00000 1994-07-17 make (AT&T Research) 5.3 2009-05-05
setv DEFINED defined
setv EMPTY
make all
exec - echo DEFINED ${DEFINED}
exec - echo DEFINED:VALUE ${DEFINED:VALUE}
exec - echo DEFINED:-VALUE ${DEFINED:-VALUE}
exec - echo DEFINED=VALUE ${DEFINED=VALUE}
exec - echo DEFINED[VALUE] ${DEFINED[VALUE]}
exec - echo DEFINED.COMPONENT ${DEFINED.COMPONENT}
exec - echo DEFINED.COMPONENT[VALUE] ${DEFINED.COMPONENT[VALUE]}
exec - echo EMPTY ${EMPTY}
exec - echo EMPTY:VALUE ${EMPTY:VALUE}
exec - echo EMPTY:-VALUE ${EMPTY:-VALUE}
exec - echo EMPTY=VALUE ${EMPTY=VALUE}
exec - echo EMPTY[VALUE] ${EMPTY[VALUE]}
exec - echo EMPTY.COMPONENT ${EMPTY.COMPONENT}
exec - echo EMPTY.COMPONENT[VALUE] ${EMPTY.COMPONENT[VALUE]}
exec - echo __NoT_DeFiNeD__ ${__NoT_DeFiNeD__}
exec - echo __NoT_DeFiNeD__:VALUE ${__NoT_DeFiNeD__:VALUE}
exec - echo __NoT_DeFiNeD__:-VALUE ${__NoT_DeFiNeD__:-VALUE}
exec - echo __NoT_DeFiNeD__=VALUE ${__NoT_DeFiNeD__=VALUE}
exec - echo __NoT_DeFiNeD__[VALUE] ${__NoT_DeFiNeD__[VALUE]}
exec - echo __NoT_DeFiNeD__.COMPONENT ${__NoT_DeFiNeD__.COMPONENT}
exec - echo __NoT_DeFiNeD__.COMPONENT[VALUE] ${__NoT_DeFiNeD__.COMPONENT[VAL'\
$'UE]}
done all generated virtual'
OUTPUT - $'echo DEFINED defined
echo DEFINED:VALUE
echo DEFINED:-VALUE
echo DEFINED=VALUE defined
echo DEFINED[VALUE] ${DEFINED[VALUE]}
echo DEFINED.COMPONENT
echo DEFINED.COMPONENT[VALUE] ${DEFINED.COMPONENT[VALUE]}
echo EMPTY
echo EMPTY:VALUE ${EMPTY:VALUE}
echo EMPTY:-VALUE ${EMPTY:-VALUE}
echo EMPTY=VALUE
echo EMPTY[VALUE] ${EMPTY[VALUE]}
echo EMPTY.COMPONENT
echo EMPTY.COMPONENT[VALUE] ${EMPTY.COMPONENT[VALUE]}
echo __NoT_DeFiNeD__ ${__NoT_DeFiNeD__}
echo __NoT_DeFiNeD__:VALUE ${__NoT_DeFiNeD__:VALUE}
echo __NoT_DeFiNeD__:-VALUE ${__NoT_DeFiNeD__:-VALUE}
echo __NoT_DeFiNeD__=VALUE ${__NoT_DeFiNeD__=VALUE}
echo __NoT_DeFiNeD__[VALUE] ${__NoT_DeFiNeD__[VALUE]}
echo __NoT_DeFiNeD__.COMPONENT
echo __NoT_DeFiNeD__.COMPONENT[VALUE] ${__NoT_DeFiNeD__.COMPONENT[VALUE]}'
ERROR -n -

View File

@@ -0,0 +1,270 @@
########################################################################
# #
# This software is part of the ast package #
# Copyright (c) 1994-2011 AT&T Intellectual Property #
# Copyright (c) 2020-2022 Contributors to ksh 93u+m #
# and is licensed under the #
# Eclipse Public License, Version 2.0 #
# #
# A copy of the License is available at #
# https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html #
# (with md5 checksum 84283fa8859daf213bdda5a9f8d1be1d) #
# #
# Glenn Fowler <gsf@research.att.com> #
# Martijn Dekker <martijn@inlv.org> #
# #
########################################################################
### this script contains archaic constructs that work with all sh variants ###
# mamprobe - generate MAM cc probe info
# Glenn Fowler <gsf@research.att.com>
(command set -o posix) 2>/dev/null && set -o posix
command=mamprobe
bins=`
(
userPATH=$PATH
PATH=/run/current-system/sw/bin:/usr/xpg7/bin:/usr/xpg6/bin:/usr/xpg4/bin:/bin:/usr/bin:$PATH
getconf PATH 2>/dev/null && echo "$userPATH" || echo /bin:/usr/bin:/sbin:/usr/sbin:"$userPATH"
) | sed 's/:/ /g'
` || exit
# check the options
opt=
case `(getopts '[-][123:xyz]' opt --xyz; echo 0$opt) 2>/dev/null` in
0123) USAGE=$'
[-?
@(#)$Id: mamprobe (AT&T Labs Research) 2011-02-11 $
]
[+NAME?mamprobe - generate MAM cc probe info]
[+DESCRIPTION?\bmamprobe\b generates MAM (make abstract machine) \bcc\b(1)
probe information for use by \bmamake\b(1). \acc-path\a is the
absolute path of the probed compiler and \ainfo-file\a is where
the information is placed. \ainfo-file\a is usually
\b$INSTALLROOT/lib/probe/C/mam/\b\ahash\a, where \ahash\a is a hash
of \acc-path\a. Any \ainfo-file\a directories are created if needed.
If \ainfo-file\a is \b-\b then the probe information is written to
the standard output.]
[+?\bmamprobe\b and \bmamake\b are used in the bootstrap phase of
\bpackage\b(1) installation before \bnmake\b(1) is built. The
probed variable names are the \bnmake\b(1) names with a \bmam_\b
prefix, \bCC\b converted to \bcc\b, and \b.\b converted to \b_\b.
Additional variables are:]{
[+_hosttype_?the \bpackage\b(1) host type]
[+mam_cc_L?\b-L\b\adir\a supported]
[+STDCAT?command to execute for \bcat\b(1); prefixed by
\bexecrate\b(1) on \b.exe\b challenged systems]
[+STDCHMOD?command to execute for \bchmod\b(1); prefixed by
\bexecrate\b(1) on \b.exe\b challenged systems]
[+STDCMP?command to execute for \bcmp\b(1); prefixed by
\bexecrate\b(1) on \b.exe\b challenged systems]
[+STDCP?command to execute for \bcp\b(1); prefixed by
\bexecrate\b(1) on \b.exe\b challenged systems]
[+STDED?command to execute for \bed\b(1) or \bex\b(1)]
[+STDEDFLAGS?flags for \bSTDED\b]
[+STDLN?command to execute for \bln\b(1); prefixed by
\bexecrate\b(1) on \b.exe\b challenged systems]
[+STDMV?command to execute for \bmv\b(1); prefixed by
\bexecrate\b(1) on \b.exe\b challenged systems]
[+STDRM?command to execute for \brm\b(1); prefixed by
\bexecrate\b(1) on \b.exe\b challenged systems]
}
[d:debug?Enable probe script debug trace.]
info-file cc-path
[+SEE ALSO?\bexecrate\b(1), \bpackage\b(1), \bmamake\b(1), \bnmake\b(1),
\bprobe\b(1)]
'
while getopts -a "$command" "$USAGE" OPT
do case $OPT in
d) opt=-d ;;
esac
done
shift `expr $OPTIND - 1`
;;
*) while :
do case $# in
0) break ;;
esac
case $1 in
--) shift
break
;;
-) break
;;
-d) opt=-d
;;
-*) echo $command: $1: unknown option >&2
;;
*) break
;;
esac
set ''
break
done
;;
esac
# check the args
case $1 in
-) ;;
/*) ;;
*) set '' ;;
esac
case $2 in
/*) ;;
*) set '' ;;
esac
case $# in
0|1) echo "Usage: $command info-file cc-path" >&2; exit 2 ;;
esac
info=$1
shift
cc=$*
# find the make probe script
ifs=${IFS-'
'}
IFS=:
set $PATH
IFS=$ifs
script=lib/probe/C/make/probe
while :
do case $# in
0) echo "$0: ../$script: probe script not found on PATH" >&2
exit 1
;;
esac
case $1 in
'') continue ;;
esac
makeprobe=`echo $1 | sed 's,[^/]*$,'$script,`
if test -x $makeprobe
then break
fi
shift
done
# create the info dir if necessary
case $info in
/*) i=X$info
ifs=${IFS-'
'}
IFS=/
set $i
IFS=$ifs
while :
do i=$1
shift
case $i in
X) break ;;
esac
done
case $info in
//*) path=/ ;;
*) path= ;;
esac
while :
do case $# in
0|1) break ;;
esac
comp=$1
shift
case $comp in
'') continue ;;
esac
path=$path/$comp
if test ! -d $path
then mkdir $path || exit
fi
done
;;
esac
# generate info in a tmp file and rename when finished
case $info in
-) ;;
*) tmp=${TMPDIR:-/tmp}/mam$$
trap "exec >/dev/null; rm -f $tmp" 0 1 2 3 15
exec > $tmp
echo "probing C language processor $cc for mam information" >&2
;;
esac
echo "note generated by $0 for $cc"
(
set '' $opt $cc
shift
. $makeprobe "$@"
case " $CC_DIALECT " in
*" -L "*) echo "CC.L = 1" ;;
esac
) | sed \
-e '/^CC\./!d' \
-e 's/^CC./setv mam_cc_/' \
-e 's/^\([^=.]*\)\./\1_/' \
-e 's/^\([^=.]*\)\./\1_/' \
-e 's/ =//' \
-e 's/\$("\([^"]*\)")/\1/g' \
-e 's/\$(\([^)]*\))/${\1}/g' \
-e 's/\${CC\./${mam_cc_}/g'
echo 'setv _hosttype_ ${mam_cc_HOSTTYPE}'
# STD* are standard commands/flags with possible execrate(1)
if (
ed <<!
q
!
) < /dev/null > /dev/null 2>&1
then STDED=ed
else STDED=ex
fi
STDEDFLAGS=-
set STDCAT cat STDCHMOD chmod STDCMP cmp STDCP cp STDLN ln STDMV mv STDRM rm
while :
do case $# in
0|1) break ;;
esac
p=$2
for d in $bins
do if test -x $d/$p
then p=$d/$p
break
fi
done
eval $1=\$p
shift
shift
done
if execrate
then for n in STDCAT STDCHMOD STDCMP STDCP STDLN STDMV STDRM
do eval $n=\"execrate \$$n\"
done
fi
for n in STDCAT STDCHMOD STDCMP STDCP STDED STDEDFLAGS STDLN STDMV STDRM
do eval echo setv \$n \$$n
done
# all done
case $info in
-) ;;
*) exec >/dev/null
test -f "$info" && rm -f "$info"
cp "$tmp" "$info"
chmod -w "$info"
;;
esac

View File

@@ -0,0 +1,78 @@
#!/bin/sh
########################################################################
# #
# This software is part of the ast package #
# Copyright (c) 1994-2011 AT&T Intellectual Property #
# and is licensed under the #
# Eclipse Public License, Version 2.0 #
# #
# A copy of the License is available at #
# https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html #
# (with md5 checksum 84283fa8859daf213bdda5a9f8d1be1d) #
# #
# Glenn Fowler <gsf@research.att.com> #
# #
########################################################################
: mkdir for systems that do not support -p : 2002-09-01 :
(command set -o posix) 2>/dev/null && set -o posix
MKDIR=mkdir
CHMOD=chmod
mode=
parents=
while :
do case $1 in
-m) case $# in
1) echo "mkdir: -m: mode argument expected" >&2
exit 1
;;
esac
shift
mode=$1
;;
-m*) mode=`echo X$1 | sed 's/X-m//'`
;;
-p) parents=1
;;
*) break
;;
esac
shift
done
if test "" != "$parents"
then for d
do if test ! -d $d
then ifs=${IFS-'
'}
IFS=/
set '' $d
IFS=$ifs
shift
dir=$1
shift
if test -n "$dir" -a ! -d "$dir"
then $MKDIR "$dir" || exit 1
if test "" != "$mode"
then $CHMOD "$mode" "$dir" || exit 1
fi
fi
for d
do dir=$dir/$d
if test ! -d "$dir"
then $MKDIR "$dir" || exit 1
if test "" != "$mode"
then $CHMOD "$mode" "$dir" || exit 1
fi
fi
done
fi
done
else $MKDIR "$@" || exit 1
if test "" != "$mode"
then for d
do $CHMOD "$mode" "$d" || exit 1
done
fi
fi
exit 0

View File

@@ -0,0 +1,641 @@
########################################################################
# #
# This software is part of the ast package #
# Copyright (c) 1994-2011 AT&T Intellectual Property #
# Copyright (c) 2020-2022 Contributors to ksh 93u+m #
# and is licensed under the #
# Eclipse Public License, Version 2.0 #
# #
# A copy of the License is available at #
# https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html #
# (with md5 checksum 84283fa8859daf213bdda5a9f8d1be1d) #
# #
# Glenn Fowler <gsf@research.att.com> #
# Martijn Dekker <martijn@inlv.org> #
# Johnothan King <johnothanking@protonmail.com> #
# #
########################################################################
: mktest - generate regress or shell regression test scripts
command=mktest
stdin=8
stdout=9
PREFIX=test
STYLE=regress
WIDTH=80
eval "exec $stdout>&1"
case $(getopts '[-][123:xyz]' opt --xyz 2>/dev/null; echo 0$opt) in
0123) ARGV0="-a $command"
USAGE=$'
[-?
@(#)$Id: mktest (AT&T Labs Research) 2010-08-11 $
]
[-author?Glenn Fowler <gsf@research.att.com>]
[-copyright?Copyright (c) 2005-2012 AT&T Intellectual Property]
[-license?https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html]
[+NAME?mktest - generate a regression test scripts]
[+DESCRIPTION?\bmktest\b generates regression test scripts from test
template commands in the \aunit\a.\brt\b file. The generated test
script writes temporary output to '$PREFIX$'\aunit\a.tmp and compares
it to the expected output in '$PREFIX$'\aunit\a.out. Run the test
script with the \b--accept\b option to (re)generate
'$PREFIX$'\aunit\a.out.]
[s:style?The script style:]:[style:='$STYLE$']
{
[+regress?\bregress\b(1) command input.]
[+shell?Standalone test shell script.]
}
[w:width?Set the output format width to approximately
\awidth\a.]:[width:='$WIDTH$']
unit.rt [ unit [ arg ... ] ]
[+INPUT FILES?The regression test command file \aunit\a\b.rt\b is a
\bksh\b(1) script that makes calls to the following functions:]
{
[+DATA \afile\a [ - | [ options ]] data]]?Create input data
\afile\a that is empty (-) or contains \adata\a subject to
\bprint\b(1) \aoptions\a or that is a copy of the DATA command
standard input. Set \afile\a to \b-\b to name the standard
input.]
[+DIAGNOSTICS?Diagnostic messages of unspecified format are
expected.]
[+DO \acommand\a [ \aarg\a ... ]]?Execute \acommand\a if the
current test is active.]
[+EXEC [ \aarg\a ... ]]?Run the command under test with
optional arguments. If the standard input is not specified then
the standard input of the previous EXEC is used. The standard
input of the first EXEC in a TEST group is an empty regular
file.]
[+EXPORT \aname\a=\avalue\a ...?Export list for subsequent
commands in the TEST group or for all TEST groups if before
the first TEST group.]
[+IGNORESPACE [ 0 | 1 ]
?Ignore space differences when comparing expected output.]
[+KEEP \apattern\a ...?File match patterns of files to retain
between TEST groups.]
[+NOTE \acomment\a?\acomment\a is added to the current test
script.]
[+PROG \acommand\a [ \aarg\a ... ]]?Run \acommand\a with
optional arguments.]
[+TEST [ \anumber\a ]] [ \adescription\a ... ]]?Define a new
test group with optional \anumber\a and \adescription\a.]
[+TWD [ \adir\a ... ]]?Set the temporary test dir to \adir\a.
The default is \aunit\a\b.tmp\b, where \aunit\a is the test
input file sans directory and suffix. If \adir\a matches \b/*\b
then it is the directory name; if \adir\a is non-null then the
prefix \b${TMPDIR:-/tmp}\b is added; otherwise if \adir\a is
omitted then
\b${TMPDIR:-/tmp}/tst-\b\aunit\a-$$-$RANDOM.\b\aunit\a is
used.]
[+UMASK [ \amask\a ]]?Run subsequent tests with \bumask\b(1)
\amask\a. If \amask\a is omitted then the original \bumask\b is
used.]
[+UNIT \acommand\a [ \aarg\a ... ]]?Define the command and
optional default arguments to be tested. \bUNIT\b explicitly
overrides the default command name derived from the test script
file name.]
[+WIDTH \awidth\a?Set the output format width to approximately
\awidth\a.]
}
[+SEE ALSO?\bregress\b(1), \bksh\b(1)]
'
;;
*) ARGV0=""
USAGE='s: unit.rt [ arg ... ]'
;;
esac
typeset ARG SCRIPT UNIT TEMP=${TMPDIR:-/tmp}/$command.$$.tmp WORK
typeset IO INPUT INPUT_N OUTPUT OUTPUT_N ERROR ERROR_N KEEP
typeset -C STATE
typeset -A DATA STATE.RESET REMOVE FORMAT
integer KEEP_UNIT=0 SCRIPT_UNIT=0 TEST=0 CODE=0 EXIT=0 ACCEPT=0 DIAGNOSTICS=0 code
while getopts $ARGV0 "$USAGE" OPT
do case $OPT in
s) case $OPTARG in
regress|shell)
STYLE=$OPTARG
;;
*) print -u2 -r -- $command: --style=$OPTARG: regress or shell expected
exit 1
;;
esac
;;
w) WIDTH=$OPTARG
;;
*) OPTIND=0
getopts $ARGV0 "$USAGE" OPT '-?'
exit 2
;;
esac
done
shift $OPTIND-1
typeset SINGLE= quote='%${SINGLE}..${WIDTH}q'
if [[ $1 == - ]]
then shift
fi
if (( ! $# ))
then
print -u2 -r -- $command: test command script path expected
exit 1
fi
SCRIPT=$1
shift
if [[ ! -r $SCRIPT ]]
then print -u2 -r -- $command: $SCRIPT: cannot read
exit 1
fi
(ulimit -c 0) >/dev/null 2>&1 && ulimit -c 0
if (( $# ))
then set -A UNIT -- "$@"
KEEP_UNIT=1
else ARG=${SCRIPT##*/}
set -A UNIT -- "${ARG%.*}"
fi
WORK=${UNIT[0]}.tmp
rm -rf $WORK
mkdir $WORK || exit
export PATH=$PWD:$PATH
function LINE
{
if [[ $STYLE == regress ]]
then print -u$stdout
fi
}
function NOTE
{
case $STYLE in
regress)LINE
print -u$stdout -r -- '#' "$@"
;;
shell) print -u$stdout -r -f ": $QUOTE"$'\n' -- "$*"
;;
esac
}
function UNIT
{
(( KEEP_UNIT )) || set -A UNIT -- "$@"
case $STYLE in
regress)LINE
print -u$stdout -r -f $'UNIT'
for ARG in "$@"
do print -u$stdout -r -f " $QUOTE" -- "$ARG"
done
print -u$stdout
;;
shell) print -u$stdout -r -f $'set x'
for ARG in "$@"
do print -u$stdout -r -f " $QUOTE" -- "$ARG"
done
print -u$stdout
print -u$stdout shift
;;
esac
}
function TEST
{
typeset i
typeset -A REM
if (( ${#STATE.RESET[@]} ))
then unset ${!STATE.RESET[@]}
case $STYLE in
shell) print -u$stdout -r -- unset ${!STATE.RESET[@]} ;;
esac
unset STATE.RESET
typeset -A STATE.RESET
fi
if (( ${#REMOVE[@]} ))
then rm -f -- "${!REMOVE[@]}"
case $STYLE in
shell) print -u$stdout -r -f $'rm -f'
for i in ${!REMOVE[@]}
do print -u$stdout -r -f " $QUOTE" "$i"
done
print -u$stdout
;;
esac
for i in ${!REMOVE[@]}
do unset REMOVE[$i]
done
fi
rm -rf $WORK/*
if [[ $1 == +([0-9]) ]]
then TEST=${1##0}
shift
else ((TEST++))
fi
LINE
case $STYLE in
regress)print -u$stdout -r -f "TEST %02d $QUOTE"$'\n' -- $TEST "$*"
;;
shell) print -u$stdout -r -f ": TEST %02d $QUOTE"$'\n' -- $TEST "$*"
;;
esac
: > $TEMP.INPUT > $TEMP.in
INPUT=
INPUT_N=
OUTPUT=
OUTPUT_N=
ERROR=
ERROR_N=
UMASK=$UMASK_ORIG
UMASK_DONE=$UMASK
CODE=0
}
function TWD
{
case $STYLE in
regress)LINE
print -u$stdout -r -f $'TWD'
for ARG in "$@"
do print -u$stdout -r -f " $QUOTE" -- "$ARG"
done
print -u$stdout
;;
esac
}
function RUN
{
typeset i n p op unit sep output=1 error=1 exitcode=1
op=$1
shift
while :
do case $1 in
++NOOUTPUT) output= ;;
++NOERROR) error= ;;
++NOEXIT) exitcode= ;;
++*) print -u2 -r -- $command: $0: $1: unknown option; exit 1 ;;
*) break ;;
esac
shift
done
if [[ $op == PROG ]]
then unit=$1
shift
elif (( ! ${#UNIT[@]} ))
then print -u2 -r -- $command: $SCRIPT: UNIT statement or operand expected
exit 1
fi
LINE
case $STYLE in
regress)if [[ $op == PROG ]]
then print -u$stdout -r -f $'\t'"$op"$'\t'"$unit"
sep=$' '
else print -u$stdout -r -f $'\t'"$op"
sep=$'\t'
fi
for ARG in "$@"
do LC_CTYPE=C print -u$stdout -r -f "$sep$QUOTE" -- "$ARG"
sep=$' '
done
print -u$stdout
[[ ${DATA[-]} || /dev/fd/0 -ef /dev/fd/$stdin ]] || cat > $TEMP.in
IO=$(cat $TEMP.in; print :)
if [[ $IO == ?*$'\n:' ]]
then IO=${IO%??}
n=
else IO=${IO%?}
n=-n
fi
{
[[ $UMASK != $UMASK_ORIG ]] && umask $UMASK
cd $WORK
if [[ $op == PROG ]]
then "$unit" "$@"
code=$?
else "${UNIT[@]}" "$@"
code=$?
fi
cd ..
[[ $UMASK != $UMASK_ORIG ]] && umask $UMASK_ORIG
} < $TEMP.in > $TEMP.out 2> $TEMP.err
if [[ $IO != "$INPUT" || $n != "$INPUT_N" ]]
then INPUT=$IO
INPUT_N=$n
if [[ ${FORMAT[-]} ]]
then print -u$stdout -n -r -- $'\t\tINPUT'
print -u$stdout -r -f " $QUOTE" -- "${FORMAT[-]}"
print -u$stdout -r -f " $QUOTE" -- -
unset FORMAT[-]
else print -u$stdout -n -r -- $'\t\tINPUT' $n -
[[ $IO ]] && LC_CTYPE=C print -u$stdout -r -f " $QUOTE" -- "$IO"
fi
print -u$stdout
unset DATA[-]
fi
for i in ${!DATA[@]}
do if [[ ${FORMAT[$i]} ]]
then print -u$stdout -n -r -- $'\t\tINPUT'
print -u$stdout -r -f " $QUOTE" -- "${FORMAT[$i]}"
print -u$stdout -r -f " $QUOTE" -- "$i"
unset FORMAT[$i]
else case $i in
-) p=$TEMP.in ;;
*) p=$WORK/$i ;;
esac
IO=$(cat $p; print :)
if [[ $IO == ?*$'\n:' ]]
then IO=${IO%??}
n=
else IO=${IO%?}
n=-n
fi
print -u$stdout -n -r -- $'\t\tINPUT' $n
print -u$stdout -r -f " $QUOTE" -- "$i"
[[ $IO ]] && LC_CTYPE=C print -u$stdout -r -f " $QUOTE" -- "$IO"
fi
print -u$stdout
unset DATA[$i]
done
IO=$(cat $TEMP.out; print :)
if [[ $IO == ?*$'\n:' ]]
then IO=${IO%??}
n=
else IO=${IO%?}
n=-n
fi
if [[ $IO != "$OUTPUT" || $n != "$OUTPUT_N" ]]
then OUTPUT=$IO
OUTPUT_N=$n
if [[ $output ]]
then if [[ ! -s $TEMP.out ]]
then print -u$stdout -n -r -- $'\t\tOUTPUT' -
elif cmp -s $TEMP.in $TEMP.out
then OUTPUT=not-$OUTPUT
print -u$stdout -n -r -- $'\t\tSAME OUTPUT INPUT'
else print -u$stdout -n -r -- $'\t\tOUTPUT' $n -
[[ $IO ]] && LC_CTYPE=C print -u$stdout -r -f " $QUOTE" -- "$IO"
fi
print -u$stdout
fi
fi
IO=$(cat $TEMP.err; print :)
IO=${IO//$command\[*([0-9])\]:\ .\[*([0-9])\]:\ @(EXEC|PROG)\[*([0-9])\]:\ /}
if [[ $IO == ?*$'\n:' ]]
then IO=${IO%??}
n=
else IO=${IO%?}
n=-n
fi
if [[ $IO != "$ERROR" || $n != "$ERROR_N" ]]
then ERROR=$IO
ERROR_N=$n
if [[ $error ]]
then print -u$stdout -n -r -- $'\t\tERROR' $n -
[[ $IO ]] && LC_CTYPE=C print -u$stdout -r -f " $QUOTE" -- "$IO"
print -u$stdout
fi
fi
case $output:$error in
:) OUTPUT=
OUTPUT_N=
ERROR=
ERROR_N=
print -u$stdout -r -- $'\t\tIGNORE OUTPUT ERROR'
;;
:1) OUTPUT=
OUTPUT_N=
print -u$stdout -r -- $'\t\tIGNORE OUTPUT'
;;
1:) ERROR=
ERROR_N=
print -u$stdout -r -- $'\t\tIGNORE ERROR'
;;
esac
if [[ $UMASK_DONE != $UMASK ]]
then UMASK_DONE=$UMASK
print -u$stdout -r -f $'\t\tUMASK %s\n' $UMASK
fi
if (( code != CODE ))
then (( CODE=code ))
if [[ $exitcode ]]
then print -u$stdout -r -f $'\t\tEXIT %d\n' $CODE
fi
fi
;;
shell) [[ $UMASK != $UMASK_ORIG ]] && print -u$stdout -r -f "{ umask $UMASK; "
if [[ $op == PROG ]]
then print -u$stdout -r -f $'"'"$unit"$'"'
else print -u$stdout -r -f $'"$@"'
fi
for ARG in "$@"
do print -u$stdout -r -f " $QUOTE" -- "$ARG"
done
[[ $UMASK != $UMASK_ORIG ]] && print -u$stdout -r -f "umask $UMASK_ORIG; } "
if [[ ! $output ]]
then print -u$stdout -r -f " >/dev/null"
fi
if [[ ! $error ]]
then if [[ ! $output ]]
then print -u$stdout -r -f " 2>&1"
else print -u$stdout -r -f " 2>/dev/null"
fi
fi
IO=$(cat)
if [[ $IO ]]
then print -u$stdout -r -- "<<'!TEST-INPUT!'"
print -u$stdout -r -- "$IO"
print -u$stdout -r -- !TEST-INPUT!
else print -u$stdout
fi
if [[ $exitcode ]]
then print -u$stdout -r -- $'CODE=$?\ncase $CODE in\n0) ;;\n*) echo exit status $CODE ;;\nesac'
fi
;;
esac
}
function DO
{
LINE
print -r $'\t'DO "$@"
}
function EXEC
{
RUN EXEC "$@"
}
function DATA
{
typeset f p o
f=$1
shift
case $f in
-) p=$TEMP.in ;;
*) p=$WORK/$f ;;
esac
case $1 in
'') cat ;;
-) ;;
*) print -r "$@" ;;
esac > $p
DATA[$f]=1
if (( $# == 1 )) && [[ $1 == -?* ]]
then FORMAT[$f]=$1
else FORMAT[$f]=
fi
if [[ $f != $KEEP ]]
then REMOVE[$f]=1
fi
if [[ $STYLE == shell ]]
then {
print -r -f "cat > $QUOTE <<'!TEST-INPUT!'"$'\n' -- "$f"
cat "$p"
print -r -- !TEST-INPUT!
} >&$stdout
fi
}
function KEEP
{
typeset p
for p
do if [[ $KEEP ]]
then KEEP=$KEEP'|'
fi
KEEP=$KEEP$p
done
}
function DIAGNOSTICS
{
LINE
case $STYLE in
regress) print -u$stdout -r $'DIAGNOSTICS' ;;
shell) DIAGNOSTICS=1 ;;
esac
}
function EXPORT
{
typeset x n v
LINE
case $STYLE in
regress) print -u$stdout -r -f $'EXPORT' ;;
shell) print -u$stdout -r -f $'export' ;;
esac
for x
do n=${x%%=*}
v=${x#*=}
export "$x"
print -u$stdout -r -f " %s=$QUOTE" "$n" "$v"
(( TEST )) && STATE.RESET["$n"]=1
done
print -u$stdout
}
function PROG
{
RUN PROG "$@"
}
function WIDTH
{
WIDTH=${1:-80}
eval QUOTE='"'$quote'"'
}
function IGNORESPACE
{
IGNORESPACE=-b
LINE
print -u$stdout -r IGNORESPACE
}
function UMASK # [ mask ]
{
[[ $UMASK_ORIG ]] || UMASK_ORIG=$(umask)
UMASK=$1
[[ $UMASK ]] || UMASK=$UMASK_ORIG
}
trap 'CODE=$?; rm -rf $TEMP.* $WORK; exit $CODE' 0 1 2 3 15
typeset IGNORESPACE UMASK UMASK_ORIG UMASK_DONE
UMASK_ORIG=$(umask)
IFS=$IFS$'\n'
print -u$stdout -r "# : : generated from $SCRIPT by $command : : #"
case $STYLE in
shell) cat <<!
ACCEPT=0
while :
do case \$1 in
-a|--accept)
ACCEPT=1
;;
--help|--man)
cat 1>&2 <<!!
Usage: \\\$SHELL $PREFIX${UNIT[0]}.sh [ --accept ] [ unit ... ]
${UNIT[0]} regression test script. Run this script to generate new
results in $PREFIX${UNIT[0]}.tmp and compare with expected results in
$PREFIX${UNIT[0]}.out. The --accept option generates $PREFIX${UNIT[0]}.tmp
and moves it to $PREFIX${UNIT[0]}.out.
!!
exit 2
;;
-*) echo \$0: \$1: invalid option >&2
exit 1
;;
*) break
;;
esac
shift
done
export COLUMNS=80
{
!
;;
esac
export COLUMNS=80
case $STYLE in
shell) SINGLE='#'
eval QUOTE='"'$quote'"'
. $SCRIPT < /dev/null | sed -e $'s,\\\\n,\n,g' -e $'s,\\\\t,\t,g' -e $'s,\\$\',\',g'
;;
*) eval QUOTE='"'$quote'"'
: > $TEMP.INPUT > $TEMP.in
eval "exec $stdin<$TEMP.INPUT"
. $SCRIPT <&$stdin
;;
esac
case $STYLE in
shell) cat <<!
} > $PREFIX${UNIT[0]}.tmp 2>&1 < /dev/null
case \$ACCEPT in
0) if grep '
$' $PREFIX${UNIT[0]}.tmp >/dev/null
then mv $PREFIX${UNIT[0]}.tmp $PREFIX${UNIT[0]}.junk
sed 's/
$//' < $PREFIX${UNIT[0]}.junk > $PREFIX${UNIT[0]}.tmp
rm -f $PREFIX${UNIT[0]}.junk
fi
if cmp -s $PREFIX${UNIT[0]}.tmp $PREFIX${UNIT[0]}.out
then echo ${UNIT[0]} tests PASSED
rm -f $PREFIX${UNIT[0]}.tmp
else echo ${UNIT[0]} tests FAILED
diff $IGNORESPACE $PREFIX${UNIT[0]}.tmp $PREFIX${UNIT[0]}.out
fi
;;
*) mv $PREFIX${UNIT[0]}.tmp $PREFIX${UNIT[0]}.out
;;
esac
!

View File

@@ -0,0 +1,27 @@
########################################################################
# #
# This software is part of the ast package #
# Copyright (c) 1994-2011 AT&T Intellectual Property #
# Copyright (c) 2020-2022 Contributors to ksh 93u+m #
# and is licensed under the #
# Eclipse Public License, Version 2.0 #
# #
# A copy of the License is available at #
# https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html #
# (with md5 checksum 84283fa8859daf213bdda5a9f8d1be1d) #
# #
# Glenn Fowler <gsf@research.att.com> #
# Martijn Dekker <martijn@inlv.org> #
# #
########################################################################
: mam probe script
opt=
while :
do case $1 in
-d) opt=-d ;;
-*) ;;
*) break ;;
esac
shift
done
mamprobe $opt - "$1"

View File

@@ -0,0 +1,28 @@
/***********************************************************************
* *
* This software is part of the ast package *
* Copyright (c) 1994-2011 AT&T Intellectual Property *
* Copyright (c) 2020-2022 Contributors to ksh 93u+m *
* and is licensed under the *
* Eclipse Public License, Version 2.0 *
* *
* A copy of the License is available at *
* https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html *
* (with md5 checksum 84283fa8859daf213bdda5a9f8d1be1d) *
* *
* Glenn Fowler <gsf@research.att.com> *
* Martijn Dekker <martijn@inlv.org> *
* *
***********************************************************************/
/*
* small test for -lnsl
*/
extern void* gethostbyname();
int
main()
{
return gethostbyname(0) == 0;
}

View File

@@ -0,0 +1,21 @@
/***********************************************************************
* *
* This software is part of the ast package *
* Copyright (c) 1994-2011 AT&T Intellectual Property *
* Copyright (c) 2020-2022 Contributors to ksh 93u+m *
* and is licensed under the *
* Eclipse Public License, Version 2.0 *
* *
* A copy of the License is available at *
* https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html *
* (with md5 checksum 84283fa8859daf213bdda5a9f8d1be1d) *
* *
* Glenn Fowler <gsf@research.att.com> *
* Martijn Dekker <martijn@inlv.org> *
* *
***********************************************************************/
/*
* small test for prototyping cc
*/
int main(int argc, char** argv) { return argc || argv; }

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,262 @@
:
# @(#)probe.win32 (AT&T Research) 2010-01-01
#
# Win32 specific make C probe initialization
# wrapped cc's are easy on UWIN
#
# 2> easy.err to avoid mysterious hang with bcc
# begin preamble shared with the pp probe.ini
IFS=$'\n'
chmod 777 . # cl.exe setuid workaround
typeset -A header version
# we are probing on behalf of libpp and nmake
# so the native preprocessor must be forced in
# order to bootstrap libpp and nmake
nativepp=-1
export nativepp
probe_header="
stddef.h
"
for inc in syslimits.h winerror.h ostream bits/ctype_base.h stream.h
do echo "#include <$inc>" > easy.c
if $cc -E easy.c > /dev/null 2> easy.err
then probe_header="$probe_header
$inc
"
fi
done
{
for i in $probe_header
do echo "#include <$i>"
done
echo '#ifdef __BORLANDC__'
echo "int _Pr0b3_version_BORLAND=__BORLANDC__;"
echo '#endif'
echo '#ifdef __DMC__'
echo "int _Pr0b3_version_DM=__DMC__;"
echo '#endif'
echo '#ifdef _MSC_VER'
echo "int _Pr0b3_version_MS=_MSC_VER;"
echo '#endif'
echo '#ifdef __ICL'
echo "int _Pr0b3_version_ICL=__ICL;"
echo '#endif'
echo '#ifdef __LCC__'
echo "int _Pr0b3_version_LCC=0+__LCC__;"
echo '#endif'
echo '#ifdef __MINGW32__'
echo "int _Pr0b3_version_MINGW=__MINGW32__;"
echo '#endif'
echo '#ifdef __INTERIX'
echo "int _Pr0b3_version_INTERIX=__INTERIX;"
echo '#endif'
echo '#ifdef __WATCOMC__'
echo "int _Pr0b3_version_WATCOM=__WATCOMC__;"
echo '#endif'
} > easy.c
include=
$cc -E easy.c 2>&1 |
egrep -i '^(#(line)? 1 .*\.[hH]| *int +_Pr0b3_[a-zA-Z_]* *= *[0-9])' |
sed -e 's,_Pr0b3_,,' \
-e 's/.*"\(.*\)".*/\1/' \
-e 's,^ *,,' \
-e 's, *$,,' \
-e 's, *= *,=,' \
-e 's,^\(.\):[\\/]*,/\1/,' \
-e 's,[\\/][\\/]*,/,g' \
-e 's,^\(/.*\)/\(.*\)$,header[\2]="\1",' \
-e 's, *int *\(.*\);.*,\1,' \
-e 's,^version_\(.*\)=,version[\1]=,' \
> easy.sh
. ./easy.sh
include=
for i in $probe_header
do d=${header[$i]}
if [[ $d ]]
then include="$include
$d"
elif [[ $i == */* ]]
then d=${header[${i##*/}]}
if [[ $d == */${i%/*} ]]
then include="$include
${d%/${i%/*}}"
fi
fi
done
i=$($cc -V 2> easy.err)
if test "" != "$i" -a -d "$i/include"
then include="$i/include
$include"
fi
stdinclude=
for inc in $include
do if [[ ${inc%/*} -ef /msdev/platformsdk ]]
then inc=/msdev/platformsdk/${inc##*/}
elif [[ ${inc%/*} -ef /platformsdk ]]
then inc=/platformsdk/${inc##*/}
fi
for dup in $stdinclude
do [[ $inc -ef $dup ]] && continue 2
done
stdinclude="$stdinclude
$inc"
done
# end preamble shared with the pp probe.ini
if [[ ${version[@]} == [0-9]* && $stdinclude ]]
then : the payoff
set -- $cc
cmd=$1
shift
set -- $(whence $cmd) "$@"
typ=$(package)
dialect="ANSI CLOSURE DYNAMIC EXPORT=DLL LIBPP -I-"
ld=${cc%cc}ld
if [[ ! -x $ld ]]
then ld=${cc%/*}/ld
if [[ ! -x $ld ]]
then case $cc in
*/ncc) ld=/usr/bin/nld ;;
*) ld=/usr/bin/ld ;;
esac
fi
fi
{
if $cc -v >/dev/null 2>&1
then v=$($cc -v 2>/dev/null)
if [[ $v ]]
then print "# ;VERSION;-v;$v;PATH;$cc"
fi
else v=
fi
cat <<!
CC.CC = $*
CC.NATIVE = $*
CC.EXECTYPE = $typ
CC.HOSTTYPE = $typ
CC.ALTPP.FLAGS = -Yp,\$(CPP:D)
CC.ALTPP.ENV =
CC.AR = ar
CC.ARFLAGS =
CC.DEBUG = -g
CC.DIALECT = $dialect
CC.DLL = -D_BLD_DLL
CC.DLLBIG = -D_BLD_DLL
CC.DLL.DEF = -D_BLD_DLL
CC.DLL.DIR = \$(BINDIR)
CC.DLL.LIBRARIES =
CC.DLL.VARIANTS =
CC.DYNAMIC =
CC.EXPORT.DYNAMIC =
CC.LD = $ld
CC.LD.DYNAMIC = -Bdynamic
CC.LD.LAZY =
CC.LD.NOLAZY =
CC.LD.ORIGIN =
CC.LD.RECORD =
CC.LD.NORECORD =
CC.LD.RUNPATH =
CC.LD.STATIC = -Bstatic
CC.LD.STRIP =
CC.LIB.DLL = option
CC.LIB.ALL = -Bwhole-archive
CC.LIB.UNDEF = -Bno-whole-archive
CC.MAKE.OPTIONS = nativepp=0
CC.NM = nm
CC.NMEDIT =
CC.NMFLAGS =
CC.OPTIMIZE = -O
CC.PIC =
CC.PICBIG =
CC.READONLY =
CC.REPOSITORY =
CC.SHARED = -G
CC.SHARED.LD = $ld
CC.SHARED.REGISTRY =
CC.SHARED.REGISTRY.PATH =
CC.SHELLMAGIC =
CC.SIZE = size
CC.STATIC = -Bstatic
!
inc=
lib=
if [[ ${version[LCC]} ]]
then lib=/lcc
fi
if [[ $stdinclude == *' '* ]]
then stdinclude=${stdinclude//' '/''}
fi
stdinc=
stdlib=
for inc in $stdinclude
do stdinc="$stdinc $inc"
d=${inc%/*}/lib
if [[ -d $d ]]
then stdlib="$stdlib $d"
fi
done
cat <<!
CC.STDINCLUDE = $stdinc
CC.STDLIB = $stdlib
!
cat <<!
CC.STRICT =
CC.STRIP = strip
CC.STRIP.FLAGS =
CC.PREFIX.ARCHIVE = lib
CC.PREFIX.DYNAMIC =
CC.PREFIX.SHARED =
CC.PREFIX.SYMBOL = _
CC.SUFFIX.ARCHIVE = .a
CC.SUFFIX.COMMAND =
CC.SUFFIX.DEBUG = .pdb
CC.SUFFIX.DYNAMIC = .dll
CC.SUFFIX.LD = .def .exp .ign .res
CC.SUFFIX.OBJECT = .o
CC.SUFFIX.SHARED = .lib
CC.SUFFIX.SOURCE = .c
CC.SUFFIX.STATIC =
!
if [[ $v ]]
then case $v in
*\"*) v=$(print -r -- | sed -e 's,",\\",g' -e 's,^ ,,' -e 's,.*,"&",') ;;
*\'*) v=\"$v\" ;;
esac
cat <<!
CC.VERSION = -v
CC.VERSION.STRING = $v
!
else cat <<!
CC.VERSION =
CC.VERSION.STRING =
!
fi
if [[ ${version[MINGW]} || ${version[MS]} ]]
then cat <<!
CC.WARN = -Wall
!
else cat <<!
CC.WARN =
!
fi
cat <<!
CC.PREROOT =
CC.UNIVERSE = att
!
} >&3
exit 0
fi

View File

@@ -0,0 +1,35 @@
########################################################################
# #
# This file is part of the ksh 93u+m package #
# Copyright (c) 2021 Contributors to ksh 93u+m #
# <https://github.com/ksh93/ksh> #
# and is licensed under the #
# Eclipse Public License, Version 2.0 #
# #
# A copy of the License is available at #
# https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html #
# (with md5 checksum 84283fa8859daf213bdda5a9f8d1be1d) #
# #
# Martijn Dekker <martijn@inlv.org> #
# #
########################################################################
# proto(1) has been removed. This is a backwards compatibility stub that allows
# compiling older AST code (with Mamfiles containing proto commands) using the
# current INIT system. This stub ignores all options, then invokes 'cat'.
while getopts ':dfhinprstvzPSC:e:l:o:L:' opt
do case $opt in
\?) case $OPTARG in
+) ;;
*) echo "proto: $OPTARG: unknown option"
echo 'Usage: proto [-dfhinprstvzP+S] [-C directory] [-e package] [-l file]'
echo ' [-o "name='\''value'\'' ..."] [-L file] file ...'
exit 2
;;
esac >&2
;;
esac
done
shift $((OPTIND - 1))
exec cat -- "$@"

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,32 @@
########################################################################
# #
# This software is part of the ast package #
# Copyright (c) 1994-2011 AT&T Intellectual Property #
# Copyright (c) 2020-2022 Contributors to ksh 93u+m #
# and is licensed under the #
# Eclipse Public License, Version 2.0 #
# #
# A copy of the License is available at #
# https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html #
# (with md5 checksum 84283fa8859daf213bdda5a9f8d1be1d) #
# #
# Glenn Fowler <gsf@research.att.com> #
# Martijn Dekker <martijn@inlv.org> #
# #
########################################################################
# non-ksh stub for the nmake silent prefix
# @(#)silent (ksh 93u+m) 2021-12-31
while :
do case $# in
0) exit 0 ;;
esac
case $1 in
*=*) export "$1"
shift
;;
*) break
;;
esac
done
"$@"

View File

@@ -0,0 +1,30 @@
/***********************************************************************
* *
* This software is part of the ast package *
* Copyright (c) 1994-2011 AT&T Intellectual Property *
* Copyright (c) 2020-2022 Contributors to ksh 93u+m *
* and is licensed under the *
* Eclipse Public License, Version 2.0 *
* *
* A copy of the License is available at *
* https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html *
* (with md5 checksum 84283fa8859daf213bdda5a9f8d1be1d) *
* *
* Glenn Fowler <gsf@research.att.com> *
* Martijn Dekker <martijn@inlv.org> *
* *
***********************************************************************/
/*
* small test for -lnsl
*/
#ifndef socket
#include <sys/types.h>
#include <sys/socket.h>
#endif
int
main()
{
return socket(0, 0, 0) < 0;
}

View File

@@ -0,0 +1,27 @@
/***********************************************************************
* *
* This software is part of the ast package *
* Copyright (c) 1994-2011 AT&T Intellectual Property *
* Copyright (c) 2020-2022 Contributors to ksh 93u+m *
* and is licensed under the *
* Eclipse Public License, Version 2.0 *
* *
* A copy of the License is available at *
* https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html *
* (with md5 checksum 84283fa8859daf213bdda5a9f8d1be1d) *
* *
* Glenn Fowler <gsf@research.att.com> *
* Martijn Dekker <martijn@inlv.org> *
* *
***********************************************************************/
#ifndef DONTCARE
#include <wchar.h>
#include <wctype.h>
#endif
int
main()
{
wchar_t w = ' ';
return iswspace(w) == 0;
}

View File

@@ -0,0 +1,24 @@
/***********************************************************************
* *
* This software is part of the ast package *
* Copyright (c) 1994-2011 AT&T Intellectual Property *
* Copyright (c) 2020-2022 Contributors to ksh 93u+m *
* and is licensed under the *
* Eclipse Public License, Version 2.0 *
* *
* A copy of the License is available at *
* https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html *
* (with md5 checksum 84283fa8859daf213bdda5a9f8d1be1d) *
* *
* Glenn Fowler <gsf@research.att.com> *
* Martijn Dekker <martijn@inlv.org> *
* *
***********************************************************************/
#include <wchar.h>
int
main()
{
wchar_t w = ' ';
return iswspace(w) == 0;
}

View File

@@ -0,0 +1,15 @@
note *
note * This build file is in the Make Abstract Machine (MAM) language. It was
note * first generated by nmake, but in the ksh 93u+m distribution we maintain
note * it manually because nmake had too many problems to keep using. The
note * Mamfiles are processed by mamake (src/cmd/INIT/mamake.c); we added
note * indentation to improve readability. The language is documented in
note * src/cmd/INIT/README-mamake.md.
note *
make test
make install
make all
exec - ${MAMAKE} -r '*' ${MAMAKEARGS}
done all virtual
done install virtual
done test virtual

View File

@@ -0,0 +1,66 @@
note *
note * This build file is in the Make Abstract Machine (MAM) language. It was
note * first generated by nmake, but in the ksh 93u+m distribution we maintain
note * it manually because nmake had too many problems to keep using. The
note * Mamfiles are processed by mamake (src/cmd/INIT/mamake.c); we added
note * indentation to improve readability. The language is documented in
note * src/cmd/INIT/README-mamake.md.
note *
setv INSTALLROOT ../../..
setv PACKAGE_ast_INCLUDE ${INSTALLROOT}/include/ast
setv PACKAGE_cmd ${INSTALLROOT}
setv PACKAGEROOT ../../../../..
setv CC cc
setv mam_cc_FLAGS
setv CCFLAGS ${-debug-symbols?1?${mam_cc_DEBUG} -D_BLD_DEBUG?${mam_cc_OPTIMIZE}?}
setv CCLDFLAGS ${-strip-symbols?1?${mam_cc_LD_STRIP}??}
setv IFFEFLAGS
setv LDFLAGS
make .INIT
make ${PACKAGE_ast_INCLUDE}/cmdlist.h
done ${PACKAGE_ast_INCLUDE}/cmdlist.h
exec - sed -e '/^CMDLIST(.*)$/!d' -e 's/CMDLIST(\(.*\))/\1/' -e '/^getconf$/d' -e '/^ln$/d' -e '/^mv$/d' -e '/^md5sum$/d' -e '/^sum$/d' ${PACKAGE_ast_INCLUDE}/cmdlist.h
bind -lcmd
done .INIT dontcare virtual
make install
make pty
make pty.o
make pty.c
make FEATURE/pty implicit
make features/pty
done features/pty
exec - iffe ${IFFEFLAGS} -v -c "${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${LDFLAGS}" ref ${mam_cc_L+-L${INSTALLROOT}/lib} -I${PACKAGE_ast_INCLUDE} -I${INSTALLROOT}/include ${mam_libast} ${mam_libcmd} : run features/pty
done FEATURE/pty generated
make ${PACKAGE_ast_INCLUDE}/ast_time.h implicit
done ${PACKAGE_ast_INCLUDE}/ast_time.h
prev ${PACKAGE_ast_INCLUDE}/vmalloc.h implicit
prev ${PACKAGE_ast_INCLUDE}/regex.h implicit
make ${PACKAGE_ast_INCLUDE}/proc.h implicit
prev ${PACKAGE_ast_INCLUDE}/ast.h implicit
done ${PACKAGE_ast_INCLUDE}/proc.h
prev ${PACKAGE_ast_INCLUDE}/error.h implicit
prev ${PACKAGE_ast_INCLUDE}/cmd.h implicit
done pty.c
prev pty.c
exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -I${PACKAGE_ast_INCLUDE} -DERROR_CATALOG=\""builtin"\" -D_PACKAGE_ast -DCMD_STANDALONE=b_pty -c pty.c
done pty.o generated
bind -lutil dontcare
exec - ${CC} ${CCLDFLAGS} ${mam_cc_FLAGS} ${CCFLAGS} ${LDFLAGS} ${mam_cc_L+-L.} ${mam_cc_L+-L${INSTALLROOT}/lib} -o pty pty.o ${mam_libutil} ${mam_libast} -lm ${mam_libcmd}
done pty generated
make ${INSTALLROOT}/bin
exec - if silent test ! -d ${INSTALLROOT}/bin
exec - then mkdir -p ${INSTALLROOT}/bin
exec - fi
done ${INSTALLROOT}/bin generated
make ${INSTALLROOT}/bin/pty
prev pty
exec - ${STDCMP} 2>/dev/null -s pty ${INSTALLROOT}/bin/pty || { ${STDMV} ${INSTALLROOT}/bin/pty ${INSTALLROOT}/bin/pty.old 2>/dev/null || true; ${STDCP} pty ${INSTALLROOT}/bin/pty ;}
done ${INSTALLROOT}/bin/pty generated
make ${INSTALLROOT}/bin
exec - if silent test ! -d ${INSTALLROOT}/bin
exec - then mkdir -p ${INSTALLROOT}/bin
exec - fi
done ${INSTALLROOT}/bin virtual
done install virtual
make test
done test dontcare virtual

View File

@@ -0,0 +1,14 @@
This file is of historical interest only. For recent changes in both ksh 93u+m
and the accompanying libraries, see the file NEWS in the top-level directory.
____
12-02-28 pty.c: change --verbose[=level] to --debug=level
12-01-26 pty.c: fix --man docs
10-06-21 pty.c: add 4 sec timeout for initial handshake -- fix me!!
10-04-12 pty: fix sfpoll() result read/write bug
10-04-01 pty: add --tty='stty-settings'
10-03-19 pty: add --dialogue
10-03-15 pty: fix select() fd management
09-03-31 features/pty,Makefile: add pty.h and -lutil refs for Linux -- great, another util library
09-01-30 pty.c: add <ast_time.h> (for fd_set!! on mvs.390)
06-07-20 pty.c: add

View File

@@ -0,0 +1,63 @@
header sys/types.h
header pty.h
header libutil.h
header sys/pty.h
header sys/ptyio.h
header sys/vty.h
header sys/ioctl.h
header stropts.h
lib openpty,_getpty,ptsname -lutil
lib grantpt,unlockpt,posix_openpt stdlib.h
lib cfmakeraw termios.h
# try once with -lm, once without
tst - -lm - - output{
#include <fcntl.h>
#if _lib_ptsname
#include <stdlib.h>
#endif
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sfio.h>
int main()
{
int i;
struct stat statb;
static char* pty[] = { "/dev/ptyp0000", "/dev/ptym/ptyp0", "/dev/ptyp0" };
#if _lib_ptsname
int fd;
static char* ptc[] = { "/dev/ptmx", "/dev/ptc", "/dev/ptmx_bsd" };
for (i = 0; i < sizeof(ptc) / sizeof(ptc[0]); i++)
if((fd = open(ptc[i], 2))>=0)
{
if (ptsname(fd))
{
sfprintf(sfstdout, "#define _pty_clone\t\"%s\"\n", ptc[i]);
close(fd);
break;
}
close(fd);
}
#endif
for (i = 0;; i++)
if(i >= (sizeof(pty) / sizeof(pty[0]) - 1) || stat(pty[i], &statb)>=0)
{
sfprintf(sfstdout, "#define _pty_first\t\"%s\"\n", pty[i]);
break;
}
return 0;
}
}end fail{
case ${_features_pty_TRIEDONCE-no} in
no) _features_pty_TRIEDONCE=yes ;;
*) echo "$0: Output block failed to compile. Export IFFEFLAGS=-d1 to debug." >&2
exit 1 ;;
esac
}end
extern _getpty char* (int*, int, mode_t, int)
extern openpty int (int*, int*, char*, struct termios*, struct winsize*)
extern ptsname char* (int)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,320 @@
ksh 93u+m/1.0.0 vs. ksh 93u+
The following is a list of changes between ksh 93u+ 2012-08-01 and the new
ksh 93u+m reboot that could cause incompatibilities in rare corner cases.
Fixes of clear bugs in ksh 93u+ are not included here, even though any bugfix
could potentially cause an incompatibility in a script that relies on the bug.
For more details, see the NEWS file and for complete details, see the git log.
0. A new '-o posix' shell option has been added to ksh 93u+m that makes
the ksh language more compatible with other shells by following the
POSIX standard more closely. See the manual page for details. It is
enabled by default if ksh is invoked as sh.
1. Bytecode compiled by shcomp 93u+m will not run on older ksh versions.
(However, bytecode compiled by older shcomp will run on ksh 93u+m.)
2. Pathname expansion (a.k.a. filename generation, a.k.a. globbing) now
never matches the special navigational names '.' (current directory)
and '..' (parent directory). This change makes a pattern like .*
useful; it now matches all hidden 'dotfiles' in the current directory.
3. The bash-style &>foo redirection operator (shorthand for >foo 2>&1) can
now always be used if -o posix is off, and not only in profile scripts.
4. Redirections that store a file descriptor > 9 in a variable, such as
{var}>file, now continue to work if brace expansion is turned off.
5. Most predefined aliases have been converted to regular built-in
commands that work the same way. 'unalias' no longer removes these.
To remove a built-in command, use 'builtin -d'. The 'history' and 'r'
predefined aliases remain, but are now only set on interactive shells.
There are some minor changes in behavior in some former aliases:
- 'redirect' now checks if all arguments are valid redirections
before performing them. If an error occurs, it issues an error
message instead of terminating the shell.
- 'suspend' now refuses to suspend a login shell, as there is probably
no parent shell to return to and the login session would freeze.
If you really want to suspend a login shell, use 'kill -s STOP $$'.
- 'times' now gives high precision output in a POSIX compliant format.
6. 'command' and 'nohup' no longer expand aliases in their first argument,
as this is no longer required after the foregoing change. In the
unlikely event that you still need this behavior, you can set:
alias command='command '
alias nohup='nohup '
7. The 'login' and 'newgrp' special built-in commands have been removed,
so it is no longer an error to define shell functions by these names.
These built-ins replaced your shell session with the external commands
by the same name, as in 'exec'. If an error occurred (e.g. due to a
typo), you would end up immediately logged out, except on a few
commercial Unix systems whose 'login' and 'newgrp' cope with this
by starting a new shell session upon error. If you do want the old
behavior, you can restore it by setting:
alias login='exec login'
alias newgrp='exec newgrp'
8. 'case' no longer retries to match patterns as literal strings if they
fail to match as patterns. This undocumented behaviour broke validation
use cases that are expected to work. For example:
n='[0-9]'
case $n in
[0-9]) echo "$n is a digit" ;;
esac
would output "[0-9] is a digit". In the unlikely event that a script
does rely on this behavior, it can be fixed like this:
case $n in
[0-9] | "[0-9]")
echo "$n is a digit or the digit pattern" ;;
esac
9. If 'set -u'/'set -o nounset' is active, then the shell now errors out
if a nonexistent positional parameter such as $1, $2, ... is accessed.
(This does *not* apply to "$@" and "$*".)
10. If 'set -u'/'set -o nounset' is active, then the shell now errors out
if $! is accessed before the shell has launched any background process.
11. The 'print', 'printf' and 'echo' built-in commands now return a nonzero
exit status if an input/output error occurs.
12. Four obsolete date format specifiers for 'printf %(format)T' were
changed to make them compatible with modern date(1) commands:
- %k and %l now return a blank-padded hour (24-hour and 12-hour clock).
- %f now returns a date with the format '%Y.%m.%d-%H:%M:%S'.
- %q now returns the quarter of the current year.
13. The 'typeset' built-in now properly detects and reports options that
cannot be used together if they are given as part of the same command.
14. The DEBUG trap has reverted to pre-93t behavior. It is now once again
reset like other traps upon entering a subshell or ksh-style function,
as documented, and it is no longer prone to crash or get corrupted.
15. 'command -x' now always runs an external command, bypassing built-ins.
16. Unbalanced quotes and backticks now correctly produce a syntax error
in -c scripts, 'eval', and backtick-style command substitutions.
17. -G/--globstar: Symbolic links to directories are now followed if they
match a normal (non-**) glob pattern. For example, if '/lnk' is a
symlink to a directory, '/lnk/**' and '/l?k/**' now work as expected.
18. The variable name search expansions ${!prefix@} and ${!prefix*} now
also include the variable 'prefix' itself in the possible results.
19. [[ -v var ]] is now properly equivalent to [[ -n ${var+set} ]].
Undocumented special-casing for numeric types has been removed.
For example, the following no longer produces an unexpected error:
$ ksh -o nounset -c 'float n; [[ -v n ]] && echo $n'
20. If the HOME variable is unset, the bare tilde ~ now expands to the
current user's system home directory instead of merely the username.
21. On Windows/Cygwin, globbing is no longer case-insensitive by default.
Turning on the new --globcasedetect shell option restores
case-insensitive globbing for case-insensitive file systems.
22. If $PWD or $OLDPWD are passed as invocation-local assignments to cd,
their values are no longer altered in the outer scope when cd finishes.
For example:
ksh -c 'OLDPWD=/bin; OLDPWD=/tmp cd - > /dev/null; echo $OLDPWD'
ksh -c 'cd /var; PWD=/tmp cd /usr; echo $PWD'
now prints '/bin' followed by '/var'.
23. Path-bound built-ins (such as /opt/ast/bin/cat) can now be executed
by invoking the canonical path, so the following will now work:
$ /opt/ast/bin/cat --version
version cat (AT&T Research) 2012-05-31
$ (PATH=/opt/ast/bin:$PATH; "$(whence -p cat)" --version)
version cat (AT&T Research) 2012-05-31
In the event an external command by that path exists, the path-bound
built-in will now override it when invoked using the canonical path.
To invoke a possible external command at that path, you can still use
a non-canonical path, e.g.: /opt//ast/bin/cat or /opt/ast/./bin/cat
24. The readonly attribute of ksh variables is no longer imported from
or exported to other ksh shell instances through the environment.
25. Subshells (even if non-forked) now keep a properly separated state
of the pseudorandom generator used for $RANDOM, so that using
$RANDOM in a non-forked subshell no longer influences a reproducible
$RANDOM sequence in the parent environment. In addition, upon
invoking a subshell, $RANDOM is now reseeded (as mksh and bash do).
26. The built-in arithmetic function int() has changed to round towards
zero instead of negative infinity. Previously, int() was an alias to
floor(), but now it behaves like trunc().
27. The '!' logical negation operator in the '[[' compound command now
correctly negates another '!', e.g., [[ ! ! 1 -eq 1 ]] now returns
0/true. Note that this has always been the case for 'test'/'['.
28. By default, arithmetic expressions in ksh no longer interpret a number
with a leading zero as octal in any context. Use 8#octalnumber instead.
Before, ksh would arbitrarily recognize the leading octal zero in some
contexts but not others. One of several examples is:
x=010; echo "$((x)), $(($x))"
would output '10, 8'. This now outputs '10, 10'. Arithmetic
expressions now also behave identically within and outside ((...))
and $((...)). Setting the --posix compliance option turns on the
recognition of the leading octal zero for all arithmetic contexts.
29. It is now an error for arithmetic expressions to assign an out-of-range
index value to a variable of an enumeration type created with 'enum'.
30. For the 'return' built-in command, you can now freely specify any
return value that fits in a signed integer, typically a 32-bit value.
Note that $? is truncated to 8 bits when the current (sub)shell exits.
31. The 'enum' and 'typeset -T' commands are no longer allowed to
override and replace special built-in commands, except for type
definition commands previously created by these commands.
32. The .sh.level variable is now read-only except inside a DEBUG trap.
The current level/scope is now restored when the DEBUG trap run ends.
____________________________________________________________________________
KSH-93 VS. KSH-88
(Written by David Korn for ksh 93u+ 2012-08-01)
The following is a list of known incompatibilities between ksh-93 and ksh-88.
I have not included cases that are clearly bugs in ksh-88. I also have
omitted features that are completely upward compatible.
1. Functions, defined with name() with ksh-93 are compatible with
the POSIX standard, not with ksh-88. No local variables are
permitted, and there is no separate scope. Functions defined
with the function name syntax have local variables as in ksh-88,
but are statically scoped as in C so that a function does not
automatically have access to local variables of the caller.
This change also affects function traces.
2. ! is now a reserved word. As a result, any command by that
name will no longer work with ksh-93.
3. The -x attribute of alias and typeset -f is no longer
effective and the ENV file is only read for interactive
shells. You need to use FPATH to make function definitions
visible to scripts.
4. A built-in command named command has been added which is
always found before the PATH search. Any script which uses
this name as the name of a command (or function) will not
be compatible.
5. The output format for some built-ins has changed. In particular
the output format for set, typeset and alias now have single
quotes around values that have special characters. The output
for trap without arguments has a format that can be used as input.
6. With ksh-88, a dollar sign ($') followed by a single quote was
interpreted literally. Now it is an ANSI C string. You
must quote the dollar sign to get the previous behavior.
Also, a $ in front of a " indicates that the string needs
to be translated for locales other than C or POSIX. The $
is ignored in the C and POSIX locale.
7. With ksh-88, tilde expansion did not take place inside ${...}.
with ksh-93, ${foo-~} will cause tilde expansion if foo is
not set. You need to escape the ~ for the previous behavior.
8. Some changes in the tokenizing rules were made that might
cause some scripts with previously ambiguous use of quoting
to produce syntax errors.
9. Programs that rely on specific exit values for the shell,
(rather than 0 or non-zero) may not be compatible. The
exit status for many shell failures has been changed.
10. Built-ins in ksh-88 were always executed before looking for
the command in the PATH variable. This is no longer true.
Thus, with ksh-93, if you have the current directory first
in your PATH, and you have a program named test in your
directory, it will be executed when you type test; the
built-in version will be run at the point /bin is found
in your PATH.
11. Some undocumented combinations of argument passing to ksh
builtins no longer works since ksh-93 is getopts conforming
with respect to its built-ins. For example, typeset -8i
previously would work as a synonym for typeset -i8.
12. Command substitution and arithmetic expansion are now performed
on PS1, PS3, and ENV when they are expanded. Thus, ` and $(
as part of the value of these variables must be preceded by a \
to preserve their previous behavior.
13. The ERRNO variable has been dropped.
14. If the file name following a redirection symbol contain pattern
characters they will only be expanded for interactive shells.
15. The arguments to a dot script will be restored when it completes.
16. The list of tracked aliases is not displayed with alias unless
the -t option is specified.
17. The POSIX standard requires that test "$arg" have exit status
of 0, if and only if $arg is null. However, since this breaks
programs that use test -t, ksh-93 treats an explicit test -t
as if the user had entered test -t 1.
18. The ^T directive of emacs mode has been changed to work the
way it does in gnu-emacs.
19. ksh-88 allowed unbalanced parentheses within ${name op val} whereas
ksh-93 does not. Thus, ${foo-(} needs to be written as ${foo-\(}
which works with both versions.
[2021 UPDATE: This is now once again allowed in ksh 93u+m. Note that
balanced parentheses ${foo-()} were also broken and are now fixed.]
20. kill -l in ksh-93 lists only the signal names, not their numerical
values.
21. Local variables defined by typeset are statically scoped in
ksh-93. In ksh-88 they were dynamically scoped although this
behavior was never documented.
22. The value of the variable given to getopts is set to ? when
the end-of-options is reached to conform to the POSIX standard.
23. Since the POSIX standard requires that octal constants be
recognized, doing arithmetic on typeset -Z variables can
yield different results that with ksh-88. Most of these
differences were eliminated in ksh-93o. Starting in ksh-93u+, the
let command no longer recognizes octal constants starting with 0
for compatibility with ksh-88 unless the option letoctal is on.
24. Starting after ksh-93l, If you run ksh name, where name does
not contain a /, the current directory will be searched
before doing a path search on name as required by the POSIX
shell standard.
25. In ksh-93, cd - will output the directory that it changes
to on standard output as required by X/Open. With ksh-88,
this only happened for interactive shells.
26. As an undocumented feature of ksh-88, a leading 0 to an
assignment of an integer variable caused that variable
to be treated as unsigned. This behavior was removed
starting in ksh-93p.
27. The getopts builtin in ksh-93 requires that optstring contain
a leading + to allow options to begin with a +.
28. In emacs/gmacs mode, control-v will not display the version when
the stty lnext character is set to control-v or is unset.
The sequence escape control-v will display the shell version.
29. In ksh-88, DEBUG traps were executed after each command. In ksh-93
DEBUG traps are executed before each command.
30. In ksh-88, a redirection to a file name given by an empty string was
ignored. In ksh-93, this is an error.
I am interested in expanding this list so please let me know if you
uncover any others.

View File

@@ -0,0 +1,168 @@
Here is an overview of the source code organization for ksh93.
Directory layout:
The directory include contains header files for ksh93.
The files nval.h and shell.h are intended to be public
headers and can be used to add runtime builtin command.
The remainder are private.
The directory data contains readonly data files for ksh93.
The man pages for built-ins are in builtins.c rather
than included as statics with the implementations in the
bltins directory because some systems don't make static const
data readonly and we want these to be shared by all running
shells.
The directory edit contains the code for command line
editing and history.
The fun directory contains some shell function such as
pushd, popd, and dirs.
The directory features contains files that are used to generate
header files in the FEATURE directory. Most of these files
are in a format that is processed by iffe.
The directory bltins contains code for most of the built-in
commands. Additional built-in commands are part of libcmd.
The directory sh contains most of the code for ksh93.
The directory tests contains a number of regression tests.
In most cases, when a bug gets fixed, a test is added to
one of these files. The regression tests can be run by
going to this directory and running
SHELL=shell_path shell_path shtests
where shell_path is an absolute pathname for the shell to
be tested.
The top level directory contains the nmake Makefile, the
RELEASE file, the ksh93 man file (sh.1) and nval.3 and shell.3
documentation files. The RELEASE file contains the list of bug
fixes and new features since the original ksh93 release. The file
COMPATIBILITY is a list of all known incompatibilities with ksh88.
Include directory:
1. argnod.h contains the type definitions for command
nodes, io nodes, argument nodes, and for positional
parameters. It defines the prototypes for
all the positional parameters functions.
2. builtins.h contains prototypes for builtins as well
as symbolic constants that refer to the name-pairs
that are associated with some of the built-ins.
It also contains prototypes for many of the strings.
3. defs.h is the catch all for all definitions that
don't fit elsewhere and it includes several other
headers. It defines a structure that contains ksh
global data, sh, and a structure that contains per
function data, sh.st.
4. edit.h contains definitions that are common to both
vi and emacs edit modes.
5. fault.h contains prototypes for signal related
functions and trap and fault handling.
6. fcin.h contains macro and function definitions for
reading from a file or string.
7. history.h contains macros and functions definitions
related to history file processing.
8. jobs.h contains the definitions relating to job
processing and control.
9. lexstates.h contains the states associated with
lexical processing.
10. name.h contains the internal definitions related
to name-value pair processing.
11. national.h contains a few I18N definitions, mostly
obsolete.
12. nval.h is the public interface to the name-value
pair library that is documented with nval.3.
13. path.h contains the interface for pathname processing
and pathname searching.
14. shell.h is the public interface for shell functions
that are documented int shell.3.
15. shlex.h contains the lexical token definitions and
interfaces for lexical analysis.
16. shnodes.h contains the definition of the structures
for each of the parse nodes and flags for the attributes.
17. shtable.h contains some interfaces and functions for
table lookup.
18. streval.h contains the interface to the arithmetic
functions.
19. terminal.h is a header file that includes the appropriate
terminal include.
20. test.h contains the definitions for the test and [[ ... ]]
commands.
21. timeout.h contains the define constant for the maximum
shell timeout.
22. ulimit.h includes the appropriate resource header.
23. variables.h contains symbolic constants for the built-in
shell variables.
24. version.h contains the version string for this release.
sh directory:
1. args.c contains functions for parsing shell options
and for processing positional parameters.
2. arith.c contains callback functions for the streval.c
library and the interface to shell arithmetic.
3. array.c contains the code for indexed and associative
arrays.
4. defs.c contains the data definitions for global symbols.
5. (removed)
6. expand.c contains code for file name expansion and
pathname expansion.
7. fault.c contains code for signal processing, trap
handling and termination.
8. fcin.c contains code for reading and writing a character
at a time from a file or string.
9. init.c contains initialization code and callbacks
for get and set functions for built-in variables.
10. io.o contains code for redirections and managing file
descriptors and file streams.
11. jobs.c contains the code for job management.
12. lex.c contains the code for the lexical analyzer.
13. macro.c contains code for the $ macro expansions, including
here-documents.
14. main.c contains the calls to initialization, profile
processing and the main evaluation loop as well as
mail processing.
15. name.c contains the name-value pair routines that are
built on the hash library in libast.
16. nvdisc.c contains code related to name-value pair disciplines.
17. nvtree.c contains code for compound variables and for
walking the namespace.
18. nvtype.c contains most of the code related to types that
are created with typeset -T.
19. parse.c contains the code for the shell parser.
20. path.c contains the code for pathname lookup and
some path functions. It also contains the code
that executes commands and scripts.
21. pmain.c is just a calls sh_main() so that all of the
rest of the shell can be in a shared library.
22. shcomp.c contains the main program to the shell
compiler. This program parses a script and creates
a file that the shell can read containing the parse tree.
23. streval.c is an C arithmetic evaluator.
24. string.c contains some string related functions.
25. subshell.c contains the code to save and restore
environments so that subshells can run without creating
a new process.
26. suid_exec.c contains the program from running execute
only and/or setuid/setgid scripts.
27. tdump.c contains the code to dump a parse tree into
a file.
28. timers.c contains code for multiple event timeouts.
29. trestore contains the code for restoring the parse
tree from the file created by tdump.
30. waitevent.c contains the sh_waitnotify function so
that builtins can handle processing events when the
shell is waiting for input or for process completion.
31. xec.c is the main shell execution loop.
edit directory:
1. completion.c contains code for command and file generation and
completion.
2. edit.c contains common editing and terminal code for vi and
emacs.
3. emacs.c contains code for the emacs editor.
4. hexpand.c contains code for C-shell style history expansions.
5. history.c contains code for creating managing the history file.
6. vi.c contains the code for the vi editor.

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,152 @@
.sp 3
.tl ''Ksh Features That Are Obsolete in Ksh93''
.sp 2
.AL 1
.LI
Using a pair of grave accents \^\fB\(ga\fR ... \fB\(ga\fR\^
for command substitution. Use \fB$(\fR ... \fB)\fR instead.
.LI
.B FCEDIT
is an obsolete name for
the default editor name for the
.B hist
command.
.B FCEDIT
is not used when
.B HISTEDIT
is set. Use
.B HISTEDIT
instead.
.LI
The newtest (\fB[[\fR ... \fB]]\fR) operator
\fB\-a\fP \fIfile\fP
is obsolete. Use
\fB\-e\fP instead.
.LI
The newtest (\fB[[\fR ... \fB]]\fR) operator
.BR = ,
as used in
\fIstring\fP \fB=\fP \fIpattern\fP
is obsolete. Use
\fB==\fP instead.
.LI
The following obsolete arithmetic comparisons are also permitted:
.in +5
.VL 20
.LI "\fIexp1\fP \fB\-eq\fP \fIexp2\fP"
True, if
.I exp1
is equal to
.IR exp2 .
.LI "\fIexp1\fP \fB\-ne\fP \fIexp2\fP"
True, if
.I exp1
is not equal to
.IR exp2 .
.LI "\fIexp1\fP \fB\-lt\fP \fIexp2\fP"
True, if
.I exp1
is less than
.IR exp2 .
.LI "\fIexp1\fP \fB\-gt\fP \fIexp2\fP"
True, if
.I exp1
is greater than
.IR exp2 .
.LI "\fIexp1\fP \fB\-le\fP \fIexp2\fP"
True, if
.I exp1
is less than or equal to
.IR exp2 .
.LI "\fIexp1\fP \fB\-ge\fP \fIexp2\fP"
True, if
.I exp1
is greater than or equal to
.IR exp2 .
.LE \" End .VL
.in -5
.LI
Using test -t or [ -t ] without specifying the file unit number.
.LI
The
.B \-k
option to the \fBset\fR builtin is obsolete. It causes
.I all\^
variable assignment arguments are placed in the environment,
even if they occur after the command name.
The following
first prints
.B "a=b c"
and then
.BR c :
There is no alternative.
.LI
The obsolete
.B \-xf
option of the
.B typeset
command allows a function to be exported
to scripts that are executed without a separate
invocation of the shell.
Functions that need to be defined across separate
invocations of the shell should
be placed in a directory and the
.B FPATH
variable should contains the name of this directory.
They may also
be specified in the
.B ENV
file with the
.B \-xf
option of
.BR typeset .
.LI
The shell environment variable
.B FCEDIT
is obsolete. Use
.B HISTEDIT
instead.
.LI
In the
.B \-s
option
(to \fBfc\fR or \fBhist\fR command???)
(
and in obsolete versions, the editor name
.B \-
)
is used to skip the editing phase and
to re-execute the command.
.LI
The
.B \-t
option to \fBalias\fR builtin is obsolete. It
is used to set and list tracked aliases.
There is no replacement.
.LI
The shell command line option
.B \-t
is obsolete. This option causes the shell to exit after reading
and executing one command. The is no replacement (although ending
\&"command" with the exit builtin should have the same effect).
.LI
As an obsolete feature of the "set" builtin,
if the first
.I arg\^
is
.B \-
then the
.B \-x
and
.B \-v
options are turned off and the next
.I arg
is treated as the first argument.
Using
.B \+
rather than
.B \-
causes these options to be turned off.
These options can also be used upon invocation of the shell.
.LE

View File

@@ -0,0 +1,141 @@
.H 1 ksh93
KSH-93 is the most recent version of the KornShell Language
described in
"The KornShell Command and Programming Language,"
by Morris Bolsky and David Korn of AT&T Bell Laboratories, ISBN 0-13-182700-6.
The KornShell is a shell programming language,
which is upward compatible with "sh" (the Bourne Shell),
and is intended to conform to the IEEE P1003.2/ISO 9945.2 Shell and
Utilities standard.
KSH-93 provides an enhanced programming environment in
addition to the major command-entry features of the BSD
shell "csh". With KSH-93, medium-sized programming tasks can be
performed at shell-level without a significant loss in performance.
In addition, "sh" scripts can be run on KSH-93 without modification.
.P
The code should conform to the IEEE POSIX 1003.1 standard and to the
proposed ANSI C standard so that it should be portable to all
such systems. Like the previous version, KSH-88,
it is designed to accept eight bit character sets
transparently, thereby making it internationally compatible.
It can support multi-byte characters sets with some characteristics
of the character set given at run time.
.P
KSH-93 provides the following features, many of which were also inherent
in KSH-88:
.BL
.LI
Enhanced Command Re-entry Capability: The KSH-93 history
function records commands entered at any shell level and stores
them, up to a user-specified limit, even after you log off.
This allows you to re-enter long commands with a few keystrokes
- even those commands you entered yesterday.
The history file allows for eight bit characters in
commands and supports essentially unlimited size histories.
.LI
In-line Editing: In "sh", the only way to fix mistyped
commands is to backspace or retype the line. KSH-93 allows you
to edit a command line using a choice of EMACS-TC or "vi"
functions.
You can use the in-line editors to complete filenames as
you type them.
You may also use this editing feature when entering
command lines from your history file.
A user can capture keystrokes and rebind keys to customize the
editing interface.
.LI
Extended I/O Capabilities: KSH-93 provides several I/O
capabilities not available in "sh", including the ability to:
.BL
.LI
specify a file descriptor for input and output
.LI
start up and run co-processes
.LI
produce a prompt at the terminal before a read
.LI
easily format and interpret responses to a menu
.LI
echo lines exactly as output without escape processing
.LI
format output using printf formats.
.LI
read and echo lines ending in "\e".
.LE
.LI
Improved performance: KSH-93 executes many scripts faster
than the System V Bourne shell. A major reason for this is
that many of the standard utilities are built-in.
To reduce the time to initiate a command, KSH-93 allows
commands to be added as built-ins at run time
on systems that support dynamic loading such as System V Release 4.
.LI
Arithmetic: KSH-93 allows you to do integer arithmetic in any
base from two to sixty-four. You can also do double
precision floating point arithmetic.
Almost the complete set of C language operators are available
with the same syntax and precedence.
Arithmetic expressions can be used to as an argument expansion
or as a separate command.
In addition there is an arithmetic for command that works
like the for statement in C.
.LI
Arrays: KSH-93 supports both indexed and associative arrays.
The subscript for an indexed array is an arithmetic expression,
whereas, the subscript for an associative array is a string.
.LI
Shell Functions and Aliases: Two mechanisms - functions and
aliases - can be used to assign a user-selected identifier to
an existing command or shell script.
Functions allow local variables and provide scoping
for exception handling.
Functions can be searched for and loaded on first reference the
way scripts are.
.LI
Substring Capabilities: KSH-93 allows you to create a
substring of any given string either by specifying the starting
offset and length, or by stripping off leading
or trailing substrings during parameter expansion.
You can also specify attributes, such as upper and lower case,
field width, and justification to shell variables.
.LI
More pattern matching capabilities: KSH-93 allows you to specify
extended regular expressions for file and string matches.
.LI
KSH-93 uses a hierarchical name space for variables.
Compound variables can be defined and variables can
be passed by reference. In addition, each variable
can have one or more disciplines associated with
it to intercept assignments and references.
.LI
Improved debugging: KSH-93 can generate line numbers on execution
traces. Also, I/O redirections are now traced.
There is a DEBUG trap that gets evaluated before each command
so that errors can be localized.
.LI
Job Control: On systems that support job control, including
System V Release 4, KSH-93
provides a job-control mechanism almost identical to that of
the BSD "csh", version 4.1.
This feature allows you
to stop and restart programs, and to move programs between the
foreground and the background.
.LI
Added security:
KSH-93 can execute scripts which do not have read permission
and scripts which have the setuid and/or setgid set when
invoked by name, rather than as an argument to the shell.
It is possible to log or control the execution of setuid and/or
setgid scripts.
The noclobber option prevents you from accidentally erasing
a file by redirecting to an existing file.
.LI
KSH-93 can be extended by adding built-in commands at run time.
In addition, KSH-93 can be used as a library that can
be embedded into an application to allow scripting.
.LE
Documentation for KSH-93 consists of an "Introduction to KSH-93",
"Compatibility with the Bourne Shell" and a manual page and a
README file. In addition, the "New KornShell Command and Programming
Language" book is available from Prentice Hall.

View File

@@ -0,0 +1,318 @@
This directory, and its subdirectories contain the source code
for ksh-93; the language described in the second edition of
the book, "The KornShell Command and Programming Language," by
Morris Bolsky and David Korn which is published by Prentice Hall.
ksh-93 has been compiled and run on several machines with several
operating systems. The end of this file contains a partial list of
operating systems and machines that ksh-93 has been known to run on.
Most of the source code for ksh is in the src/cmd/ksh93/sh
directory. For information on what's where, see the file DESIGN.
#### COMPILE-TIME OPTIONS ####
The SHOPT.sh file contains several compilation options that can be set
before compiling ksh. Options are of the form SHOPT_option and become
#define inside the code. These options are set to their recommended
value and some of these may disappear as options in future releases.
A value of 0 represents off, 1 represents on, no value means probe. For
options where no feature probe is available, probe is the same as off.
The options have the following defaults and meanings:
ACCT off Shell accounting.
Noted by "L" in the version string when enabled.
See README-AUDIT.md.
ACCTFILE off Enable per user accounting info.
See README-AUDIT.md.
AUDIT on For auditing specific users.
Noted by "A" in the version string when enabled.
See README-AUDIT.md.
AUDITFILE "/etc/ksh_audit"
See README-AUDIT.md.
BGX on Enables background job extensions. Noted by "J" in the
version string when enabled. (1) JOBMAX=n limits the
number of concurrent background jobs to n; the (n+1)th
background job will block until a running background job
completes. (2) SIGCHLD traps are queued so that each
completing background job gets its own trap; $! is set to
the job PID and $? is set to the job exit status at the
beginning of the trap.
BRACEPAT on Brace expansion. Expands abc{d,e}f to abcdf abcef.
This feature was inspired by the C shell.
CMDLIB_HDR "<cmdlist.h>"
The header in which you can provide a custom list of
libcmd commands to provide as path-bound built-ins.
CMDLIB_DIR "\"/opt/ast/bin\""
The default virtual directory prefix for path-bound
built-ins. The value must include double quotes.
CRNL off <cr><nl> treated as <nl> in shell grammar.
DEVFD Use the more secure /dev/fd mechanism instead of FIFOs for
process substitutions. On by default on OSs with /dev/fd.
DYNAMIC off Dynamic loading of builtins. Requires dlopen() interface
and dynamic libshell, libdll and libast libraries.
ECHOPRINT off Make echo equivalent to print.
EDPREDICT off Enables history pattern search menu. As you begin a line
with a #, the following characters are treated as a shell
pattern and cause matching lines from the history file to
be displayed as a numbered list as you type. You can
scroll up and down this list or you can use <ESC>nTAB to
make this the current line (n defaults to 1 if omitted).
Experimental. Bugs: https://github.com/ksh93/ksh/issues/233
ESH on Compile with emacs command line editing. The original
emacs line editor code was provided by Mike Veach at IH.
FILESCAN on Allows fast reading of files using:
while < file; do ...; done
Each line is stored in $REPLY and fields in each
line can be accessed as positional parameters.
FIXEDARRAY on When using typeset, a name in the format NAME[N]
creates a fixed-size array and any attempt to access a
subscript N or higher is an error. Multidimensional
fixed-size arrays NAME[N1][N2]... are also supported.
GLOBCASEDET Adds the 'globcasedetect' shell option. When this shell
option is turned on, pathname expansion (globbing)
and file name listing and completion automatically become
case-insensitive on file systems where the difference
between upper- and lowercase is ignored for file names.
This compile-time option is enabled by default on operating
systems that can support case-insensitive file systems.
HISTEXPAND on Enable !-style history expansion similar to csh(1).
This is turned on by the -H/--histexpand shell option and
can be modified using --histreedit and --histverify.
KIA off Allow generation of shell cross-reference database with -R.
As of 2021-05-10, no tool that can parse this database is
known. If you know of any, please contact us.
MULTIBYTE Multibyte character handling. This is on by default unless
the flag -DAST_NOMULTIBYTE is passed to the compiler via
CCFLAGS. The UTF-8 character set is fully supported.
NAMESPACE on Adds a 'namespace' reserved word that allows defining name
spaces. Variables and functions defined within a block like
namespace ExampleSpace { commandlist; }
all have their names automatically prefixed with
'.ExampleSpace.' when defining or using them, creating a
separate space of names unique to the block. Outside of
the namespace block, they can be accessed using
.ExampleSpace.function or ${.ExampleSpace.variable}.
Name spaces within name spaces are also supported.
MKSERVICE off Enables the 'mkservice' builtin which creates a TCP or UDP
server that is implemented by shell functions, and the
'eloop' builtin which causes the shell to block waiting for
events to process. Experimental and probably insecure.
NOECHOE off Disable the '-e' option to the 'echo' command,
unless SHOPT_ECHOPRINT is enabled.
OLDTERMIO off Use either termios or termio at runtime.
OPTIMIZE on Optimize loop invariants for with for and while loops.
P_SUID 0 If set, all real UIDs greater than or equal to this value
will require the -p option to run the shell setuid/setgid.
RAWONLY on Turn on if the vi line mode doesn't work right unless
you do a set -o viraw.
REGRESS off Enable the __regress__ built-in command and instrumented
intercepts for testing.
REMOTE off Set --rc (read profile scripts) even if ksh was invoked
with standard input on a socket, i.e. as a remote shell.
SPAWN on Use posix_spawn(3) as combined fork/exec if job control
is not active. Improves speed.
STATS on Add .sh.stats compound variable.
SUID_EXEC on Execute /etc/suid_exec for setuid, setgid script.
SYSRC Source /etc/ksh.kshrc on initializing an interactive
shell. This is on by default if /etc/ksh.kshrc or
/etc/bash.bashrc exists at compile time.
TEST_L Add 'test -l' as an alias for 'test -L'. This is on by
default if the OS's external 'test' command supports it.
TIMEOUT off Set this to the number of seconds for timing out and
exiting the shell when you don't enter a command. If
non-zero, TMOUT can not be set larger than this value.
VSH on Compile with vi command line editing. The original vi
line editor code was provided by Pat Sullivan at CB.
#### BUILDING KSH 93U+M ####
To build ksh (as well as libcmd and libast libraries on which ksh depends),
cd to the top directory and run:
bin/package make
The compiled binaries are stored in the arch directory, in a subdirectory
that corresponds to your architecture. The command 'bin/package host type'
outputs the name of this subdirectory.
If you have trouble or want to tune the binaries, you may pass additional
compiler and linker flags. It is usually best to export these as environment
variables before running bin/package as they could change the name of the
build subdirectory of the arch directory, so exporting them is a convenient
way to keep them consistent between build and test commands. Note that this
system uses CCFLAGS instead of the usual CFLAGS. An example that makes
Solaris Studio cc produce a 64-bit binary:
export CCFLAGS="-m64 -O" LDFLAGS="-m64"
bin/package make
Alternatively you can append these to the command, and they will only be
used for that command. You can also specify an alternative shell in which to
run the build scripts this way. For example:
bin/package make SHELL=/bin/bash CCFLAGS="-O2 -I/opt/local/include" \
LDFLAGS="-L/opt/local/lib"
Note: Do not add compiler flags that cause the compiler to emit terminal
escape codes, such as -fdiagnostics-color=always; this will cause the build
to fail as the probing code greps compiler diagnostics.
If you are certain that you don't need support for UTF-8 and other multibyte
character locales and really want to save some memory and CPU cycles, add
'-DAST_NOMULTIBYTE' to CCFLAGS to compile out all multibyte character
handling in ksh and supporting libraries. Not recommended for most users.
To install, use: bin/package install DESTINATION_DIRECTORY [ COMMAND ... ]
Any command from the arch directory can be installed. If no COMMAND is
specified, ksh and shcomp are assumed.
The DESTINATION_DIRECTORY is created if it does not exist. Commands are
installed in its bin subdirectory and each command's manual page, if
available, is installed in share/man.
Destination directories with whitespace or shell pattern characters in their
pathnames are not yet supported.
For more information, run:
bin/package help
Many other commands in this repo self-document via the --help, --man and
--html options; those that do have no separate manual page.
The build should also generate shcomp, a program that will precompile
a script. ksh93 is able to recognize files in this format and process
them as scripts. You can use shcomp to send out scripts when you
don't want to give away the original script source.
To be able to run setuid/setgid shell scripts, or scripts without read
permission, the SUID_EXEC compile option must be on, and ksh must be installed
in the /bin directory, the /usr/bin directory, the /usr/lbin directory,
or the /usr/local/bin directory and the name must end in sh. The program
suid_exec must be installed in the /etc directory, must be owned by root,
and must be an SUID program. If you must install ksh in some other directory
and want to be able to run setuid/setgid and execute only scripts, then
you will have to change the source code file sh/suid_exec.c explicitly.
If you do not have ksh in one of these secure locations, /bin/sh will
be invoked with the -p options and will fail when you execute a setuid/setgid
and/or execute only script. Note that ksh does not read the .profile
or $ENV file when the real and effective user/group IDs are not equal.
#### TESTING KSH ####
The tests subdirectory contains a number of regression tests for ksh.
To run all these tests with the shell you just built, run the command
bin/shtests
For help and more options, type
bin/shtests --man
#### OTHER DOCUMENTATION ####
The file PROMO.mm is an advertisement that extolls the virtues of ksh.
The file sh.1 contains the troff (man) description of this Shell.
The file nval.3 contains the troff (man) description of the name-value
pair library that is needed for writing built-ins that need to
access shell variables.
The file sh.memo contains a draft troff (mm) memo describing ksh. The
file builtins.mm is a draft troff (mm) memo describing how to write
built-in commands that can be loaded at run time.
The file NEWS in the top-level directory contains bug fixes and other
changes made in the ksh 93u+m fork and supporting libraries. The file
COMPATIBILITY contains a list of potential incompatibilities.
#### TESTED SYSTEMS ####
ksh 93u+m 1.0.0.beta-1 has been compiled and tested on the following.
An asterisk signifies minor regression test failures (one or two minor
things amiss), two asterisks signify moderate regression test failures
(some functionality does not work), and three asterisks signify serious
failures (crashes, and/or important functionality does not work).
* AIX 7.1 on RISC (PowerPC)
* DragonFly BSD 5.8 on x86_64
FreeBSD 12.2 on x86_64
FreeBSD 13.0 on x86_64
FreeBSD 12.2 on arm64 (thanks to hyenias for donating access to a Pi)
GNU/Linux: Alpine 3.12.3 (musl C library) on x86_64
GNU/Linux: CentOS 8.2 on x86_64
GNU/Linux: Debian 10.7 on x86_64
GNU/Linux: Gentoo 2.7 on i386
GNU/Linux: NixOS 19.09 on x86_64
GNU/Linux: Slackware 14.2 on x86_64
GNU/Linux: Ubuntu 16.04 on x86_64
GNU/Linux: Ubuntu 18.04 on armv7l (32-bit)
GNU/Linux: Ubuntu 20.04 on arm64
GNU/Linux: Void Linux (musl C library) on x86_64
*** Haiku R1/beta3 on x86_64
*** HP-UX B.11.11 on pa-risc
* illumos: OmniOS 2020-08-19 (gcc) on x86_64
illumos: OmniOS r151040 (gcc) on x86_64
macOS 10.13.6 (High Sierra) on x86_64
macOS 10.14.6 (Mojave) on x86_64
* macOS 12.0.1 (Monterey) on arm64
* NetBSD 8.1 on x86_64
* NetBSD 9.2 on x86_64
* OpenBSD 6.8 on x86_64
OpenBSD 7.0 on x86_64
* QNX Neutrino 6.5.0 on i386
* Solaris 11.4 (gcc) on x86_64
Solaris 11.4 (Solaris Studio 12.5 cc) on x86_64
* UnixWare 7.1.4 on x86
*** Windows 7 using Cygwin on x86
*** Windows 10 using Cygwin on x86_64
*** Windows 11 using Cygwin on x86_64
Windows 11 using WSL 2 with Ubuntu 20.04 on x86_64
#### REPORTING BUGS ####
Please report any problems or suggestions by opening an issue at:
https://github.com/ksh93/ksh
Alternatively, email martijn@inlv.org (timely response *not* promised).
Good luck!!
The ksh 93u+m contributors
https://github.com/ksh93/ksh
Originally written by:
David Korn
dgk@research.att.com

View File

@@ -0,0 +1,201 @@
# Korn Shell 93 Auditing and Accounting #
This documentation was adapted from a 2008 blog post by Finnbarr P. Murphy
and was added to the ksh 93u+m distribution under the same license as ksh
by permission from the author, given on 24th Jan 2021.
[Original](https://blog.fpmurphy.com/2008/12/ksh93-auditing-and-accounting.html).
The responsibility for any errors in this file lies with the current
ksh 93u+m maintainers and not with the original author.
## Introduction ##
Korn Shell 93 (ksh93) is the only UNIX or GNU/Linux shell that I am aware
of that, with proper setup, supports a modicum of per-user accounting and
auditing. This post attempts to explain these facilities and show you how
to access and manipulate the resulting accounting and auditing records.
Per-user accounting has been a feature of ksh93 since the earliest days of this
shell. It is a fairly primitive facility which writes out a record for each
user command that is executed. By default, it is not compiled in to the shell.
An auditing facility was added in July 2008. This is somewhat more
sophisticated than the accounting facility in that it is configurable and
writes out a more detailed record either locally or to a remote system for
each user command that is executed. This facility can be used to monitor,
track, record, and audit the activities of one or more users on an system,
including system administrators. As of ksh 93u+ 2012-06-12, this is compiled
in to the shell by default.
Both facilities only work for interactive users.
To enable or disable one or both facilities, you need to modify the compile
time options in `src/cmd/ksh93/SHOPT.sh` as follows. Use `0` to disable and
`1` to enable (except for `SHOPT_AUDITFILE`). Then recompile the sources;
see `README` for building instructions.
SHOPT ACCT=1 # accounting
SHOPT ACCTFILE=1 # per-user accounting info
SHOPT AUDIT=1 # enable auditing per SHOPT_AUDITFILE
SHOPT AUDITFILE='\"/etc/ksh_audit\"' # auditing file
After you have recompiled the sources, the new ksh executable is located in the
`arch/`...`/bin` subdirectory. To see what options have actually been compiled
into a particular executable, just print out the shell version string.
$ arch/darwin.i386-64/bin/ksh -c 'echo ${.sh.version}'
Version AJLM 93u+m/1.1.0-alpha+dev 2022-01-20
$ arch/darwin.i386-64/bin/ksh -c 'echo $KSH_VERSION'
Version AJLM 93u+m/1.1.0-alpha+dev 2022-01-20
The option string AJLM means that
(A) auditing is supported (`SHOPT_AUDIT`),
(J) one SIGCHLD trap per completed job is supported (`SHOPT_BGX`),
(L) accounting is supported (`SHOPT_ACCT`), and
(M) multibyte characters are supported (`SHOPT_MULTIBYTE`).
## Accounting ##
After recompiling the shell to enable this facility, per-user accounting is
enabled using the `SHACCT` environment variable. To turn on per-user
accounting, simply set `SHACCT` to the name of the file where you wish to
store the accounting records.
export SHACCT="/tmp/ksh_acctfile"
Here is part of the resulting file. Note that the time is stored as
hexadecimal seconds since the Unix epoch (00:00:00 UTC on 1 January 1970).
$ cat /tmp/ksh_acctfile
echo ${.sh.version} fpm 495990d8
pwd fpm 495990da
id fpm 495990dd
date fpm 495990e3
exit fpm 495990e5
The following shell script can be used to access the records in this file
and output them in a more useful format.
#!/bin/ksh93
ACCTFILE="/tmp/ksh_acctfile"
printf "DATE TIME LOGIN COMMAMD\n\n"
# set IFS to TAB only
while IFS=$'\t' read cmdstr name hexseconds
do
printf -v longsecs "%ld" "0x${hexseconds}"
printf "%(%Y-%m-%d %H:%M:%S)T, %s, %s\n" "#${longsecs}" "$name" "$cmdstr"
done < $ACCTFILE
Invoking this script gives the following output for the above accounting
records.
$ ./parse_acctfile
DATE TIME LOGIN COMMAMD
2008-12-29 22:09:12, fpm, echo ${.sh.version}
2008-12-29 22:09:14, fpm, pwd
2008-12-29 22:09:17, fpm, id
2008-12-29 22:09:23, fpm, date
2008-12-29 22:09:25, fpm, exit
## Auditing ##
Next we turn our attention to the auditing facility. Assuming ksh has been
compiled with the `SHOPT_AUDIT` option (the default), you must create an audit
configuration file on each system to tell ksh93 where to store the audit
records and to specify which users are to be audited. The configuration file
must be readable by the users whose activities are audited. Its default
location is `/etc/ksh_audit` but that can be changed in the `SHOPT.sh` file.
The configuration file should contain a line that defines the file to write
the audit records to, followed by the UID of each user whose commands are to
generate audit records. Here is the configuration file used to generate the
audit records for this part of this post.
$ cat /etc/ksh_audit
/tmp/ksh_auditfile;500
This configuration file specifies that audit records are to be written to
`/tmp/ksh_auditfile` for the user whose UID is 500. Note that the field
delimiter is a semicolon.
Here are the audit records stored in `/tmp/ksh_auditfile` which match the
accounting records shown previously in this post. The field separator is a
semicolon. The first field is the UID of the user executing the command.
The second field is the time in seconds since the Epoch. The third field is
the terminal device on which the command was executed, and the final field
is the actual command executed by the user.
500;1230606552;/dev/pts/2; echo ${.sh.version}
500;1230606554;/dev/pts/2; pwd
500;1230606557;/dev/pts/2; id
500;1230606563;/dev/pts/2; date
500;1230606565;/dev/pts/2; exit
As before, here is a simple ksh93 script which parses this audit file,
replaces the UID with the actual user's name and seconds since the Epoch
with the actual date and time, and outputs the enhanced records in a comma
separated value (CSV) format.
#!/bin/ksh93
AUDITFILE="/tmp/ksh_auditfile"
while IFS=";" read uid sec tty cmdstr
do
printf '%(%Y-%m-%d %H:%M:%S)T, %s, %d, %s, %s\n' \
"#$sec" "$(id -un $uid)" "$uid" "$tty" "$cmdstr"
done < $AUDITFILE
Here is the output for the above audit records.
2008-12-29 22:09:12, fpm, 500, /dev/pts/2, echo ${.sh.version}
2008-12-29 22:09:14, fpm, 500, /dev/pts/2, pwd
2008-12-29 22:09:17, fpm, 500, /dev/pts/2, id
2008-12-29 22:09:23, fpm, 500, /dev/pts/2, date
2008-12-29 22:09:25, fpm, 500, /dev/pts/2, exit
The audit file must be writable by all users whose activities are audited,
presenting an obvious security problem. However, the Korn shell supports
networking using the `/dev/udp/`*host*`/`*port* or `/dev/tcp/`*host*`/`*port*
syntax, so audit records can be sent across a network to another system.
This mechanism could be used to store audit records on a secured centralized
system to which only specific personnel have access. As an example, the
following audit configuration file line designates that audit records for
the user whose UID is 500 should be sent using UDP to the syslog network
port (514) on a remote system whose IP is 192.168.0.99.
/dev/udp/192.168.0.99/514;500
Here are the same audit records stored by the syslog daemon on the remote system.
2008-12-29 22:09:12 192,169.0.115 500;1230606552;/dev/pts/2; echo ${.sh.version}
2008-12-29 22:09:14 192.169.0.115 500;1230606554;/dev/pts/2; pwd
2008-12-29 22:09:17 192.169.0.115 500;1230606557;/dev/pts/2; id
2008-12-29 22:09:23 192.169.0.115 500;1230606563;/dev/pts/2; date
2008-12-29 22:09:25 192.169.0.115 500;1230606565;/dev/pts/2; exit
Depending on the configuration of the syslog daemon on your particular
system, the first part of the record may contain more or less information or
be formatted differently but the final part of the record, i.e. the audit
record sent by ksh93 should be in the standard audit record format.
## Afterword ##
Note that while the auditing and accounting facilities within ksh93 can
provide you with much useful information regarding the actions of one or
more users on a system or systems, these facilities should not be regarded
as providing enhanced security akin to the Trusted Computing Base (TCB).
There are many ways of circumventing these facilities. For example, a
knowledgeable user could switch to a different shell such as bash where
their actions will not be recorded. There are a number of other ways but I
will not discuss them here.
Most of the information provided in this post is not documented in a single
place anywhere that I can find by searching the Internet. The ksh93 man page
does not mention either the accounting or auditing facilities. Even the
ksh93 source code is somewhat vague. I gleaned most of this information by
studying the code in
[`src/cmd/ksh93/edit/history.c`](https://github.com/ksh93/ksh/blob/dev/src/cmd/ksh93/edit/history.c).
*Martijn Dekker adds:* I would like to thank the author Finnbarr P. Murphy
for his permission to use his ksh93-related blog posts in the ksh 93u+m
distribution. As of 2022, this is still the only documentation available for
the facilities described. If you find any errors or omissions, please
[file an issue](https://github.com/ksh93/ksh).

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,426 @@
This file is of historic interest. For recent changes in both ksh 93u+m and
the accompanying libraries, see the file NEWS in the top-level directory.
____
This is a list of changes that have been made since the 11/16/88 version
of ksh.
1. New features in 12/28/93
a. Associative arrays. The new version of ksh supports both
associative arrays and the older indexed arrays with the same
array syntax. A new -A option of typeset is used to declare
an array to be associative. As with indexed arrays, $name is
equivalent to ${name[0]}. The prefix operator ! was added
to the parameter expansion syntax to expand to the list of
indices. For example, ${!name[@]} expands to the list of array
indices for variable name.
b. Several additions have been made to shell arithmetic:
1. The shell now performs floating point arithmetic. The
typeset options -F and -E have been added for floating
point and scientific notation respectively.
2. The prefix and postfix ++ and -- operators.
3. The comma and ?: operators.
4. The math library functions.
5. An arithmetic for statement of the form
for ((expr1; expr2; expr3))
do ...
done
6. Integer arithmetic extended up to base 64.
c. Some additions to the macro expansion syntax have been made
to specify substrings and sub-arrays:
1. ${name:expr} expands to the substring of ${name} starting at
the character position defined by arithmetic expression expr.
2. ${name:expr1:expr2} expands to the substring of ${name} starting
at expr1 and consisting of at most expr2 characters.
3. ${name[@]:expr} expands to the values of ${name[@]} starting at
the element defined by arithmetic expression expr.
4. ${name[@]:expr1:expr2} expands to at most expr2 values of
${name} starting at expr1.
5. ${@:expr} expands the positional parameters starting at expr.
6. ${@:expr1:expr2} expands to at most expr2 positional parameters
starting at expr1.
7. ${!name} expands to the name of the variable named by name.
It will expand to name unless name is a reference variable.
8. ${!name[sub]} expands to the name of the subscript of the
given variable. If sub is @ or * the list of subscripts
is generated.
9. ${!prefix*} and ${!prefix@} expand to the list of variable
names beginning with prefix.
10. The substring operators, # and % can be now be applied
with aggregates (@ or *) and are applied to each.
11. ${name/pattern/string} expands to the value of name with
the first occurrence of pattern replaced by string.
With aggregates (@ or *) this operation is applied to each.
12. ${name/#pattern/string} Same as above but the pattern
to be replaced must match at the beginning.
13. ${name/%pattern/string} Same as above but the pattern
to be replaced must match at the end.
14. ${name//pattern/string} expands to the value of name with
each occurrence of pattern replaced by string.
With aggregates (@ or *) this operation is applied to each.
d. The name space for variables has been extended. The character '.'
can be used at the beginning of a name, and to separate identifiers
within a name. However, to create a name of the form, foo.bar,
the variable foo must exist. The namespace starting with .sh
is reserved for shell implementation variables. Exported
variables cannot contain a '.'.
e. Compound assignments. The assignment syntax, varname=value,
has been extended to allow assignments of the form
varname=(assignment_list). As elsewhere in the shell
spaces or tabs are optional around the parentheses, and
no space is permitted between the varname and the =. The
assignment_list can be one of the following:
1. A list of words. In this case each word is expanded as
in a for list and the resulting items become elements
of the indexed array varname.
2. A list of subscript assignments in the form
[subscript]=value. In this, these elements become
elements of the associative array varname.
3. A list of assignments; simple or compound. In this
case, each assignment is made to varname.name, where
name is the name of the enclosed assignment.
4. Assignments in the form of readonly or typeset
statements. In this case each assignment is made as
in 3 above, and the attributes are given to the
corresponding variable.
In case 3 and 4 above, the value of "$varname" after
the above assignment is (assignment_list), where the
assignment_list produced would reproduce all of the
variables under varname.*.
f. Function names of the form variable.action (called discipline
functions) can be defined where variable is any valid variable
name and action is get, set, or unset. The function variable.get
is invoked each time the variable is referenced. The set
discipline is invoked each time the variable is assigned to.
The unset discipline is invoked when a variable is unset.
The new variables .sh.name, .sh.subscript, and .sh.value are
defined inside the function body. Other shell extensions
may have their own set of discipline functions.
g. The compound command !, which negates the return value of the
following pipeline, has been added.
h. On systems that support dynamic loading with dlopen(), it is
now possible to add built-in commands at runtime with the
builtin command named 'builtin'.
i. The following builtins have been added:
1. command name [ ... ]
2. sleep [decimal-seconds]
3. builtin [-ds] [-f file] [name...]
4. getconf name [pathname]
5. disown [job...]
j. An addition format for literal strings, $'....' can
be used where ever literal strings are valid. The string
inside the single quotes will be converted using the ANSI C
escape conventions. Additionally, the escape sequence \E
expands to the escape character (default \033) whenever ANSI C
escape sequences are recognized.
k. A typeset -n option has been added which causes the value of a
variable to be treated as a reference to another variable so that
variables can be indirectly named. For example, if $1 contains
the name of a variable, then typeset -n foo=$1 causes the variable
foo to be synonymous with the variable whose name is $1. A builtin
alias, nameref='typeset -n' has been added to aid mnemonics.
Reference names cannot contain a '.'. Whenever that portion of
a variable up to the first '.' matches a reference name, the
reference value is substituted. For example, with nameref foo=.top,
then ${foo.bar} is equivalent to ${.top.bar}. When used as the
index of a for or select loop, each assignment causes a
new name reference to occur.
l. The KEYBD trap has been added which is triggered when a key
or escape sequence is typed while reading from the keyboard
in an edit mode. This, combined with some new variables
makes it possible to program your key bindings in ksh.
m. New variables have been added:
1. FIGNORE defines a set of file names to be ignored in each
directory when performing pathname expansion, replacing
the rule that requires that a leading . be matched explicitly.
2. Variable sh.edchar contains the value of the keyboard character
that has been entered when processing a KEYBD trap. If the value
is changed as part of the trap action, then the new value replaces
the key or keys that caused the trap.
3. Variable sh.edcol is set to the character position of the cursor
within the input buffer during a KEYBD trap.
4. Variable sh.edmode is set to the escape character when in vi
insert mode.
5. Variable sh.edtext is set to the contents of the input buffer
during a KEYBD trap.
6. HISTEDIT is checked before FCEDIT. FCEDIT is obsolete.
7. HISTCMD is the number of the current command in the history
file.
8. Variable .sh.version is set to the version string for
this shell.
9. Variable .sh.name is set to the name of the variable
that was referenced or assigned to when executing a get
or set discipline function.
10. Variable .sh.subscript is set to the subscript for the variable
that was referenced or assign to when executing a get or
set discipline function.
11. Variable .sh.value is set to the new value for the variable
that was assigned to when executing the set discipline function.
n. New invocation and set -o options have been added:
1. set -o notify (or set -b) causes background completion messages
to be displayed as soon as the job completes.
2. There is a compile time option named KIA which enables
creation of a relational database for commands, variables
and functions defined and referenced by a script. The
option -I <filename>, causes the database to be generated
in <filename>. The database format can be queried via
the cql command.
o. ksh93 can read and evaluate pre-compiled scripts generated by
a separate program called shcomp.
p. More work on internationalization has been added:
1. The decimal point character is processed per locale
2. A $ can be placed in front of each string to indicate
that the string needs translation but is otherwise ignored.
This means that if a message catalog of all $"..." strings
is generated, then a program such as print $"hello world"
could display "bonjour monde" in the French locale.
q. Backreferences have been added to pattern matching. The sequence
\d, where d is a digit from 1-9, matches the same string as
the d-th previous parenthesis group. Backreferences
can be used within patterns, and within replacement strings
with any of the ${name/...} operators.
2. Changes made in 12/28/93
a. The output format of many commands has changed as follows:
1. System error messages are displayed whenever a failure
is caused by a system call.
2. The exit status has changed in many cases:
a. USAGE messages cause an exit status of 2.
b. Commands not found cause exit - 127.
c. Command found, but not executable - 126.
d. Terminated because of signal - 256+sig
3. The output of values from built-ins that contain special
characters are quoted in a manner that then can be re-input.
4. The trace output puts quotes around the output so that it
can be reused as input.
5. The output for trap is in a format that can be reinput to
the shell to restore the traps.
6. kill -l lists the signal names without numbers as
required by the POSIX standard.
b. The following changes have been made to shell functions:
1. The semantics of functions declared with name() has changed
to conform with the IEEE-POSIX 1003.2 standard. In particular,
these functions are executed in a dot script environment rather
than a separated function environment so that there are no
local variables and no scoping for traps.
2. Functions declared as function name, preserve the old ksh
semantics can be also used as the first argument to the dot (.)
command to have them executed in a dot script environment.
c. The command search rules have changed as follows:
1. Special built-ins (those with a dagger in front of them) are
executed first.
2. Functions are executed next.
3. Other built-ins that do not require an executable version
(for example cd and read) come next.
4. If the command name contains a slash, the pathname corresponding
to the command name is executed.
5. If name corresponds to a previously encountered pathname
on the PATH variable, the corresponding command is executed.
6. If the command name does not contain a slash, then the PATH
variable is used to find an executable by that name. If
the directory that the command is found is also contained in
the FPATH variable, then the command treated as a function.
If the shell has a built-in version of the command corresponding
to this command, then the built-in version of this command
is executed. Otherwise, the shell remembers that pathname
corresponding to this command name and executes this pathname.
7. If the name is not found on PATH, then the directories in
FPATH are searched. If found, then the command is executed
as a function.
d. Built-in commands options now conform to the IEEE-POSIX 1003.2
conventions with some additions. In particular,
name -?
will now print a Usage line for name, except for true, false,
colon, login, newgrp, echo, [, and command.
e. Tilde expansion is now performed as part of the word expansions.
The effect of this is that if word begins with ~ in ${name op word},
it will be expanded unless escaped.
f. Pathname expansion is no longer performed on redirection words
unless the shell is interactive.
g. Changes to shell and options:
1. The -n option has been enhanced to produce more warning and
portability messages.
2. The -C option is equivalent to -o noclobber. Files are
created with O_EXCL when -C is on.
h. The following changes have been made to [[ ... ]]:
1. A string by itself is equivalent to -n string.
2. -e has been added as equivalent to -a.
3. == has been added as equivalent =.
4. -a and = are now considered obsolete.
5. Arithmetic comparisons are now considered obsolete.
i. kill has been changed as follows:
1. Signal names can be upper case or lower case.
2. Numerical arguments to kill -l cause the given signal names to
be displayed.
3. String arguments to kill -l cause the given signal numbers to
be displayed.
4. Synopsis changed for getopts conformance.
j. print has a -f format option which is equivalent to
the IEEE POSIX printf. Both print -f format, and
printf have the following extensions from IEEE POSIX:
1. Floating point formats are supported.
2. Size and precision specifications can be *.
3. The %d option can take an argument after precision to
specify the base that the number will be displayed.
4. A %q format can be used to output a string quoted so
that it can be re-input to the shell.
5. A %P format can be used to output the shell pattern which
corresponds to the give extended regular expression.
6. For numerical fields, the arguments can be arithmetic
expressions which will be evaluated.
7. The %n format works as described in ANSI C.
k. The following changes have been made to fc:
1. It has been renamed hist. fc is now a predefined alias.
2. hist uses ${HISTEDIT:-$FCEDIT}. FCEDIT is obsolete.
3. A new -s option is equivalent to the obsolete -e -.
4. If the first argument refers to a command earlier than the
first accessible command, it now implies the first accessible
command, so that hist -l 1 lists all accessible history commands.
l. The dot command (.) has changed as follows:
1. The argument can be the name of a function declared as
function name. The function will execute without creating a
new scope.
2. If there are arguments to the given script or function,
the positional parameters are restored to their original
value when . completes.
m. The read built-in has been changed as follows:
1. A -A option to read has been added to allow the fields to be
read into an indexed array.
2. A -t n option has been added which causes read to
timeout after n seconds when reading from a slow device.
3. A -d char option has been added which causes the read
to terminate at char rather than at new-line.
n. The trap command has been changed as follows:
1. Trap names can be either upper case or lower case.
2. Trap -p only causes the specified trap values to be displayed.
3. The value of trap in a subshell will be the value in the parent
shell until a call to trap which changes the trap settings has
been made. Thus, savetraps=$(trap) works as required by the
POSIX standard.
o. The exec command has been extended as follows:
1. The -c option clears the environment first.
2. The -a name option sets argv[0] to name for the program.
p. true and false are built-ins, not aliases to built-ins.
q. test has been modified to conform to the IEEE-POSIX 1003.2
standard when there are three or less arguments.
r. umask -S option displays the mask in a symbolic format.
s. wait now returns the correct exit status of any previous
background job that has not been waited for, not just
the most recent one.
t. The whence built-in has an option -a which causes all
uses for the given command name to be reported.
u. unalias has -a option to clear all the aliases.
v. The times built-in command has been removed. The time
reserved word, without a command, gives time cumulative
time for the shell and its children. A built-in alias
for times should enable scripts using times to continue
to run.
w. Command substitution and arithmetic substitution will now be
performed for PS1, ENV, and PS4 evaluation in addition to
parameter expansion.
x. The SECONDS variable now displays elapsed time in floating
point seconds with 3 places after the decimal point by
default.
y. The getopts built-in now handles the complete libast optget
functionality. If any errors have occurred with getopts
when it has reached the end of arguments, then the Usage
message will be generated from the option string and the
exit status from getopts will be 2 rather than 1. The
usage message will be stored in the OPTARG variable if
the option string contains a leading colon; otherwise
it will be printed on standard error automatically.
z. THE ENV file is only processed for interactive shell
invocations. In addition, the -x attributes for
aliases and functions is ignored.
aa. The built-in edit modes have been changed as follows:
1. The pathname completion and pathname listing options
now perform command completion and command listing
when applied to a word in the command position.
2. In emacs mode ^N as the first related command after
the prompt will move to the next command relative to the
last known history position.
3. In emacs mode, successive kill and delete commands will
accumulate their data in the kill buffer, by appending or
prepending as appropriate. This mode will be reset by any
command not adding something to the kill buffer.
4. The control-T of emacs mode has been changed to behave like
control-T in gnu-emacs.
bb. The TMOUT variable also sets a limit for select timeouts
and default timeouts for read.
4. The source code has undergone significant modification.
a. Much of the code has been rewritten, In many cases this has
resulted in significant performance improvement.
b. The code is organized differently. See the README files
for more details.
c. Most configuration parameters now get generated using
the FEATURE mechanism of nmake. Other options are set
in the OPTIONS file.
c. There are several new compile time options. See the README
file for details. Some of the old ones have been removed.
d. The install script is a Mamfile that is generated by
nmake and processed by a script that comes with the
distribution.
e. There are far fewer global names. This should make it
must easier to add built-in commands without worrying
about conflicts.
f. The code uses the sfio library which makes it possible
to mix with stdio.
g. The code is written in ANSI C with full prototypes.
The code is based on the IEEE POSIX 1003.1 standard.
The code can be compiled with K&R C and with C++ by
using the ANSI cpp that comes with nmake or running
the code through the proto filter before pre-processing.
This happens automatically with our shipping system.
h. There is a programming interface for capturing references
and assignment to shell variables. It is also possible
to intercept variable creation and supply the array processing
function for that variable. See nval.3 for a description.

View File

@@ -0,0 +1,458 @@
This file is of historic interest. For recent changes in both ksh 93u+m and
the accompanying libraries, see the file NEWS in the top-level directory.
____
This is a list of changes that have been made since the 12/28/93 version
of ksh.
1. New features in 12/28/93b
a. If IFS contains two consecutive identical characters belonging
to the [:space:] class, then this character is treated as
a non-space delimiter so that each instance will delimit
a field. For example, IFS=$'\t\t' will cause two consecutive
tabs to delimit a null field.
b. The getopts command has a -a name option that specifies a
name that will be used for usage messages.
2. New features in 12/28/93e
a. The math functions, atan2, hypot, fmod, and pow were added.
b. When a shared library is loaded, if the function lib_init()
is defined in the library, it is invoked the first time that
the library is loaded with builtin -f library.
3. New features in 12/28/93f
a. Hostnames in addition to host addresses can be given in
/dev/tcp/host/port virtual file names.
b. File name completion and expansion now quotes special
characters in file names from both emacs and vi edit modes.
4. New features in 12/28/93g
a. The pipefail option has been added. With pipefail
enabled, a pipeline will not complete until all
commands are complete, and the return value will
be that of the last command to fail, or zero if
all complete successfully.
b. When an executable is found on a given path,
the appropriate library path variable is prepended
with a corresponding library directory.
5. New features in 12/28/93h
a. The PATH search algorithm has been modified to look
for a file named .fpath in each bin directory and if
found, to search for functions in this directory if
it cannot find the command in that directory.
b. When performing pathname expansion, the shell checks
to see whether each directory it reads is case sensitive
or not, and performs the matching accordingly.
c. The %T format for printing formatted date/time.
6. New features in 12/28/93i
a. Most of the built-in commands and ksh itself are now
self documenting. Running command --man will produce
screen output. Running command --html produces the
man page in html format.
b. The getopts builtin can process command description
strings to produce man pages.
7. Bugs fixed in 12/28/93a for default OPTIONS
a. An expansion bug which causes portions of a word after
a $((...)) expansion that contains a nested $var expansion
to be lost has been fixed.
b. A bug that caused a core dump when a script that did not
have PWD set and did a cd inside command substitution
has been fixed.
c. A bug which caused a core dump on some machines when
the LANG variable was assigned to has been fixed.
d. A bug which incorrectly handled set disciplines that
performed arithmetic evaluation when the discipline
was called from the arithmetic evaluator has been fixed.
e. A bug caused by an EXIT trap inside a function that
was executed in a subshell was fixed.
f. If foo is a function, and not a program, then command foo
now reports that foo isn't found rather than invoking foo.
g. The previous version incorrectly listed -A as an
invocation option. The -A option is only for set.
h. A bug was fixed which caused ksh to loop when execution trace
was enabled and the PS4 prompt required command substitution.
i. A bug which could cause the job control switch character
to be disabled when a script that enabled monitor mode
terminated was fixed.
j. A bug in the macro expansion global replacement operator //,
when the pattern began with a [ or +( has been fixed.
k. A bug which prevented ~ expansion from occurring when
it was terminated with a colon inside an assignment
has been fixed.
l. A bug in the dot command which prevented autoload functions
from working has been fixed.
m. A bug which caused a variable to be unset if the
its value were expanded inside a set discipline has
been fixed.
n. Whence -a now longer reports that a defined function
is undefined.
o. A bug on some systems in which $0 would be incorrect
in scripts invoked by name has been fixed.
p. Here documents with an empty body now work.
1. A bug which disabled argument passing and resetting
of options for a script invoked by name inside a
function has been fixed.
r. A bug in which an EXIT trap set the caller of a function
would be executed if a command called inside a function
was not found has been fixed.
s. A bug which allowed a script to trap signals that are
ignored at the time that the shell was invoked has
been fixed.
t. A bug which caused 2<&1- when applied to a shell built-in
to leave standard input closed has been fixed.
u. A bug which caused the shell to incorrectly parse
$() command substitutions with nested case statements
has been fixed.
8. Bugs fixed in 12/28/93b for default OPTIONS
a. A bug which caused unset RANDOM to dump core has been
fixed.
b. A bug which prevented return for terminating a profile
or ENV file has been fixed.
c. A bug which prevented standard input from being
directed to /dev/null for background jobs when
monitor mode was turned off has been fixed.
d. Statements of the form typeset -options var[expr]=value
did not perform substitutions on expr as expected.
e. A bug which prevented the shell from sending a HUP
signal to some background jobs that were not disowned
has been fixed.
f. A bug which allowed a script to trap signals that are
ignored at the time that the shell was invoked by exec
has been fixed.
g. A bug which could cause a core dump when a discipline
function was unset within a discipline was fixed.
h. The typeset builtin now accepts a first argument of
+ or - for compatibility with ksh88.
i. For compatibility with ksh88, the results of expansions
of command arguments will treat the extended character
match characters ()|& as ordinary characters.
j. A bug which caused read to fail on a file that was
open for read/write with <> when the first operation
was print or printf has been fixed.
k. When a job is suspended, it is put on the top of
the job list as required by the POSIX standard.
l. The value of OPTARG when an option that required
an argument but didn't have one was incorrect in the
case the option string began with a :.
m. A bug which caused the terminal to get into a bad
state with some KEYBD traps in vi-mode has been fixed.
n. A bug which caused an invalid trap to cause a script
to terminate, rather than just return an error, has
been fixed.
o. Backreferencing sub-expressions in patterns and replacement
strings now works.
p. A bug in chmod which caused the -R option to fail has
been fixed.
9. Bugs fixed in 12/28/93c for default OPTIONS
a. The expansion of "$@" was incorrect when $1 was the null
string.
b. A bug which could incorrectly report a syntax error in
a backquoted expression when a $ was preceded by \\
has been fixed.
c. A bug which prevented the shell from exiting after
reporting an error when failing to open a script
has been fixed.
d. A bug that could lead to memory corruption when a
large here document that required parameter or command
substitution was expanded has been fixed.
e. A bug that could cause a core dump on some systems
after ksh detected an error when reading a function
has been fixed.
f. A bug which could cause a coprocess to hang when
reading from a process that has terminated has been fixed.
g. A bug which caused a script to terminate when set -e
was on and the first command of and && or || list
failed has been fixed.
h. A bug with here documents inside $(...) when the delimiter
word is an identifier has been fixed.
i. A bug which caused $0 to display the wrong value when
a script was invoked as an argument to the . command
and the eval command has been fixed.
j. A bug that could cause the built-in sleep to hang
has been fixed.
k. A bug introduces in 12/28/93b which caused the backslash
to be removed when it was followed by digit inside double
quotes in some instances has been fixed.
l. A bug which could cause a core dump if ksh was invoked with
standard input closed has been fixed.
m. A bug which could cause a core dump if typeset -A was
specified for an existing variable has been fixed.
n. Variables that were unset but had attributes such as readonly
and export were not listed with readonly, export and typeset.
o. Several problems with signals have been fixed.
p. A bug which prevented ulimit -t from working has been fixed.
Also, a bug in which failed ulimits could cause a core dump
has also been fixed.
q. A bug in expansion of the form ${name/#pattern/string} and
${name/%pattern/string} has been fixed.
r. A bug which caused read -r on a line that contained only
blanks to get a non-null value has been fixed.
s. A bug introduced in the 'a' point release in which
${x='\\'} expanded to \ when x was unset has been fixed.
t. A bug which prevented a trap on EXIT from being executed
when the last command in a script was a function invocation
has been fixed.
u. A bug which caused an interactive shell ignore input when
standard error was redirected to a file with exec,
and then restored with exec 2>&1 has been fixed.
v. An interactive shell turns on monitor mode even when
standard error has been redirected to a file.
w. A bug which could cause standard input to be incorrectly
positioned for the last command of a script has been fixed.
y. A bug in the edit modes which allowed walking back in
the history file for more than HISTSIZE commands has
been fixed.
z. A bug which could cause a core dump if variable TMPDIR was
changed between two command substitutions has been fixed.
aa. A bug which prevented a trap on EXIT from being cleared
has been fixed.
10. Bugs fixed in 12/28/93d for default OPTIONS
a. The \ character was not handled correctly in replacement
patterns with ${x/pattern/replace}.
b. A bug with read in which the line did not end with
a new-line has been fixed.
c. A bug in file name generation which sometimes
appended a . for filenames that ended in / has
been fixed.
d. If a process is waited for after a status has
been returned by a previous wait, wait now
returns 127.
e. A bug with hist (fc) -e which prevented a command
to re-executed after it had been edited has been fixed.
f. A bug which prevented quoting from removing the meaning
of unary test operators has been fixed.
11. Bugs fixed in 12/28/93e for default OPTIONS
a. Empty command substitutions of the form $() now work.
b. whence -v foo now gives the correct result after calling
builtin -d foo.
c. A bug in right to left arithmetic assignment for which
the arithmetic expression (( y = x = 1.5 )) did not
yield 1 for y when x was declared typeset -i was fixed.
d. printf has been fixed to handle format containing \0
and/or \0145 correctly. In addition, characters following
%b in the format string are no longer displayed when
the operand contains \c.
e. A bug in printf that could cause the %E format to
produce unnormalized results has been fixed.
f. A bug which causes some arithmetic expressions to be
incorrectly evaluated as integer expressions rather
that floating point has been fixed.
g. Functions defined inside a subshell no longer remain
defined when the subshell completes.
h. The error message from sh -c ';echo foo' has been
corrected.
i. The format for umask -S has been changed to agree
with the specification in the POSIX standard.
j. A bug that caused side effects in subscript evaluation
when tracing was enabled for subscripts using ++ or --
has been fixed.
k. To conform to the POSIX standard getopts has been changed
so that the option char is set to ? when it returns with
a non-zero exit status.
l. The handling of \} inside ${name...} has been fixed so
that the \ quotes the }.
m. A bug that caused the read builtin to resume execution
after processing a trap has been fixed.
n. [[ -s file ]] has been fixed so that if file is open
by ksh, it is flushed first.
o. In some cases attributes and sizes for non exported
variables weren't being reset before running a script.
p. The value of TMOUT was affected by changes make to
it in a subshell.
q. The jobs command did not reflect changes make by
sending the CONT signal to a command.
r. The error message for ksh -o unknown was incorrect.
s. Functions invoked as name=value name, did not use
values from the calling scope when evaluating value.
t. A bug in which the shell would re-execute previously
executed code when a shell script or coprocess was
run in the background has been fixed.
u. A bug in which an empty here-document would leave
a file descriptor open has been fixed.
v. A bug in which $(set -A array ...) would leave a
side effect has been fixed.
w. A discipline function for a global variable defined
within a function defined with the function keyword,
incorrectly created a local variable of the same name
and applied the discipline to it.
12. Bugs fixed in 12/28/93f for default OPTIONS
a. A bug which would cause the secondary prompt to be
displayed when a user entered a literal carriage
return has been fixed.
b. I bug which caused ksh read -s name to core dump was
fixed.
c. I bug with the expansion of \} and \] inside double
quoted strings that also contained variable expansions
has been fixed
d. Changes in the 'e' point release caused autoload
functions invoked from within command substitution
to fail. This has been fixed.
e. A bug in the processing of here-documents that could
prevent variable substitution to occur after $(...) command
substitution for long here documents has been fixed.
f. A bug caused by a race condition that could cause SIGTERM
to be ignored by a child process has been fixed.
g. A bug which prevented the startup of a coprocess immediately
after killing a running coprocess has been fixed.
h. ulimit foobar, where foobar is not an arithmetic
expression, now gives an error message as it did with ksh88
instead of setting the file size limit to 0.
i. A bug which could cause an interactive shell to terminate when
the last process of a pipeline was a POSIX function was fixed.
j. A bug which could cause command substitution of a shell script
to core dump has been fixed.
k. A security hole was fixed in suid_exec.
l. Arithmetic functions such as pow() that take more than
one argument, did not work if arguments other than the
first contained parenthesized sub-expression.
m. The error message from a script containing an incomplete
arithmetic expression has been corrected.
n. A bug which caused a core dump on some machines when
the value of a name reference contained a positional
parameter and the name reference was not defined inside
a function has been fixed.
o. Arithmetic expressions now correctly handle hexadecimal
constants.
p. A bug in which integer variables could be expanded
with a leading 10# when declared with typeset -i
multiple times has been corrected.
q. A bug in which IFS wasn't correctly restored when
set within command substitution has been fixed.
r. The _ character is now considered as part of a word
with the M-f and M-b emacs directives as it was in ksh88.
13. Bugs fixed in 12/28/93g for default OPTIONS
a. A bug in which a name reference could be created to
itself and later cause the shell to get into an infinite
loop has been fixed.
b. A bug in shcomp relating to compound variables was fixed.
c. A bug introduced in 'e' in which leading 0's in -Z
fields caused the value to be treated as octal for arithmetic
evaluation has been fixed.
d. A bug when a name reference with a shorter name than
the variable it references was the subject of a compound
assignment has been fixed.
e. A bug which in which assignment to array variables in
a subshell could affect the parent shell has been
fixed.
f. read name?prompt was putting a 0 byte at the end of the
prompt on standard error.
g. A bug in [[ string1 > string2 ]] when ksh was run with -x
has been fixed.
k. A bug in which the escape character was not processed
correctly inside {...} when brace expansion is enabled
has been fixed, for example {\$foo}.
l. A bug in line continuation in here-documents has been
fixed.
m. The default base when not specified with typeset -i is
10 in accordance with the documentation. Previously,
the value was determined by the first assignment.
n. A parsing bug in which a # preceded alphanumeric
characters inside a command substitution caused
a syntax error to be reported has been fixed.
o. A bug in which a decimal constant represented as 10#ddd
where ddd was more than five digits generated a syntax
error has been fixed.
p. A bug in here document expansion in which ${...} expansions
were split across buffer boundaries has been fixed.
14. Bugs fixed in 12/28/93h for default OPTIONS
a. I bug in shcomp for compilation of unary operators with [[ ... ]]
has been fixed.
b. A bug in which the value of $? was changed when executing
a keyboard trap has been fixed.
c. The handling of SIGCHLD has been changed so that the
trap is not triggered while executing trap commands
to avoid recursive trap calls.
d. I bug in which a local variable in a function declared readonly
would generated an error when the function went out of
scope has been fixed.
e. I bug in which \<new_line> entered from the keyboard
with the KEYBD trap enabled has been fixed.
f. The error message for a misplaced ((, for example print ((3),
was often garbled and has been fixed.
g. I bug in the KEYBD trap in which escape sequences of the form
<ESC>[#~ were not being handled as a unit has been fixed.
h. A bug in which ksh would consider expressions like [[ (a) ]]
as syntax errors has been fixed.
i. A function defined as foo() without a function body
was not reported as a syntax error.
j. A bug in which ksh could run out of file descriptors when
a stream was repeatedly opened with exec and read from
has been fixed.
k. A bug introduced when fixing item n from the 'g' point
release has been fixed.
15. Bugs fixed in 12/28/93i for default OPTIONS
a. A bug in which a script could terminate when getopts
encountered an error when invoked inside a function
has been fixed.
b. When a symbolic link was specified as the name of
the script to invoke by name, the value of $0 was
set to the real file name rather than the link name
in some cases and this has been fixed.
16. Bug fixes for specific non-default option combinations.
a. More signal names have been added for Solaris
b. A bug fixed for the v directive in vi MULTIBYTE has been
fixed.
c. Code to for IFS handling of multibyte characters has
been added.
d. The displaying of multibyte strings in export, readonly,
typeset, and execution traces has been fixed.
e. A bug with type ahead and KEYBOARD traps with the
MULTIBYTE option set has been fixed.
f. The k-shell information abstraction database option, KIA,
has been revamped for the 'e' point release.
g. A bug in brace pattern expansions that caused expressions
such as {foo\,bar,bam} to expand incorrectly have been fixed.
h. On the U/WIN version for Window 95 and Windows NT,
when a directory beginning with a letter followed by
a colon is given to cd, it is assumed to be an absolute
directory.
i. There was a bug in the compile option that does not
use fork() in which the current option settings where
not propagated to sub-shells.
j. A bug in setting .sh.editchar during the KEYBD trap
for the MULTIBYTE option was fixed in release 'h'.
k. A bug in which the precision given as an argument
to printf was not working has been fixed.
17. Other changes to 12/28/93[abcdefghi]
a. A couple of minor changes to make adding built-ins easier.
b. Variables inside functions are now statically scoped.
The previous behavior was never documented.
c. A few changes have been made to the name-value library
that affect built-ins that use disciplines. The
changes allow disciplines to be shared by variables
and should make it possible to add new disciplines
without recompilation.
d. The name-value library interface has undergone significant
change for this revision. See the new nval.3 man page.
e. Builtin functions can take a third argument which is
a void*.
f. The nv_scan() function can restrict the scope of a walk
to the top scope. Starting in 'f', nv_scan() has an
additional pointer argument that is passed to each invoked
function.
g. Starting with release 'f', an empty for list behave like
a for list with null expansions. It produces a warning
message with sh -n.
h. Starting with release 'f' the code has been modified to
work with EBCDIC as well as ASCII.
i. Starting with the release 'g', the name-value pair library
uses the cdt library rather than the hash library.
j. The sh_fun() function now takes third argument which
is an argument list for the invoked discipline function
or built-in.
k. A callback function can be installed which will give
notification of file duplications and file closes.
18. Incompatibilities with 12/28/93 version.
None intentional.

View File

@@ -0,0 +1,43 @@
#
# Compile-time SHOPT_* options for ksh93.
# 1 to enable, 0 to disable, empty value to probe.
#
# For a more complete description of the options, see src/cmd/ksh93/README.
#
SHOPT ACCT=0 # accounting
SHOPT ACCTFILE=0 # per-user accounting info
SHOPT AUDIT=1 # enable auditing per SHOPT_AUDITFILE
SHOPT AUDITFILE='"/etc/ksh_audit"' # auditing file
SHOPT BGX=1 # one SIGCHLD trap per completed job
SHOPT BRACEPAT=1 # C-shell {...,...} expansions (, required)
SHOPT CMDLIB_HDR= # '<cmdlist.h>' # custom -lcmd list for path-bound builtins
SHOPT CMDLIB_DIR= # '"/opt/ast/bin"' # virtual directory prefix for path-bound builtins
SHOPT CRNL= # accept MS Windows newlines (<cr><nl>) for <nl>
SHOPT DEVFD= # use /dev/fd instead of FIFOs for process substitutions
SHOPT DYNAMIC=0 # dynamic loading for builtins
SHOPT ECHOPRINT= # make echo equivalent to print
SHOPT EDPREDICT=0 # History pattern search menu (type #<pattern>, then ESC <number> TAB). Experimental.
SHOPT ESH=1 # emacs/gmacs edit mode
SHOPT FILESCAN=1 # fast file scan: while <file; do [use $REPLY or positional parameters]; done
SHOPT FIXEDARRAY=1 # fixed dimension indexed array
SHOPT GLOBCASEDET= # -o globcasedetect: adapt globbing/completion to case-insensitive file systems
SHOPT HISTEXPAND=1 # csh-style history file expansions
SHOPT KIA= # ksh -R <outfile> <script> generates cross-ref database from script
SHOPT MKSERVICE=0 # enable the mkservice and eloop builtins
SHOPT MULTIBYTE= # multibyte character handling
SHOPT NAMESPACE=1 # allow namespaces
SHOPT NOECHOE=0 # turn off 'echo -e' when SHOPT_ECHOPRINT is disabled
SHOPT OLDTERMIO= # support both TCGETA and TCGETS
SHOPT OPTIMIZE=1 # optimize loop invariants
SHOPT P_SUID=0 # real UIDs >= this value require -p for set[ug]id (to turn off, use empty, not 0)
SHOPT RAWONLY=1 # make viraw the only vi mode
SHOPT REGRESS= # enable __regress__ builtin and instrumented intercepts for testing
SHOPT REMOTE= # enable --rc if running as a remote shell
SHOPT SPAWN= # use spawnveg for fork/exec
SHOPT STATS=1 # add .sh.stats variable
SHOPT SUID_EXEC=1 # allow (safe) SUID/SGID shell scripts
SHOPT SYSRC= # attempt . /etc/ksh.kshrc if interactive
SHOPT TEST_L= # add 'test -l' as an alias for 'test -L'
SHOPT TIMEOUT= # number of seconds for shell timeout
SHOPT VSH=1 # vi edit mode

View File

@@ -0,0 +1,182 @@
The ability for users to define types has been added to ksh93t.
Here is a quick summary of how types are defined and used in ksh93t.
This is still a work in progress so some changes and additions
are likely.
A type can be defined either by a shared library or by using the new
typeset -T option to the shell. The method for defining types via
a shared library is not described here. However, the source file
bltins/enum.c is an example of a builtin that creates enumeration types.
By convention, typenames begin with a capital letter and end in _t.
To define a type, use
typeset -T Type_t=(
definition
)
where definition contains assignment commands, declaration commands,
and function definitions. A declaration command (for example typeset,
readonly, and export), is a built-in that differs from other builtins in
that tilde expansion is performed on arguments after an =, assignments
do not have to precede the command name, and field splitting and pathname
expansion is not performed on the arguments.
For example,
typeset -T Pt_t=(
float -h 'length in inches' x=1
float -h 'width in inches' y=0
integer -S count=0
len()
{
print -r $((sqrt(_.x*_.x + _.y*_.y)))
}
set()
{
(( _.count++))
}
)
defines a type Pt_t that has three variables x, y, and count defined as well
as the discipline functions len and set. The variable x has an initial value
of 1 and the variable y has an initial value of 0. The new -h option argument,
is used for documentations purposes as described later and is ignored outside
of a type definition.
The variable count has the new -S attribute which means that it is shared
between all instances of the type. The -S option to typeset is ignored
outside of a type definition. Note the variable named _ that is used inside
the function definition for len and set. It will be a reference to the
instance of Pt_t that invoked the function. The functions len and set
could also have been defined with function len and function set, but
since there are no local variables, the len() and set() form are more
efficient since they don't need to set up a context for local variables
and for saving and restoring traps.
If the discipline function named create is defined it will be
invoked when creating each instance for that type. A function named
create cannot be defined by any instance.
When a type is defined, a declaration built-in command by this name
is added to ksh. As with other shell builtins, you can get the man page
for this newly added command by invoking Pt_t --man. The information from
the -h options will be embedded in this man page. Any functions that
use getopts to process arguments will be cross-referenced on the generated
man page.
Since Pt_t is now a declaration command it can be used in the definition
of other types, for example
typeset -T Rect_t=( Pt_t ur ll)
Because a type definition is a command, it can be loaded on first reference
by putting the definition into a file that is found on FPATH.
Thus, if this definition is in a file named Pt_t on FPATH, then
a program can create instances of Pt_t without first including
the definition.
A type definition is readonly and cannot be unset. Unsetting non-shared
elements of a type restores them to their default value. Unsetting a
shared element has no effect.
The Pt_t command is used to create an instance of Pt_t.
Pt_t p1
creates an instance named p1 with the initial value for p1.x set to 1
and the initial value of p1.y set to 0.
Pt_t p2=(x=3 y=4)
creates an instance with the specified initial values. The len function
gives the distance of the point to the origin. Thus, p1.len will output
1 and p2.len will output 5.
ksh93t also introduces a more efficient command substitution mechanism.
Instead of $(command), the new command substitution ${ command;}
can be used. Unlike (and ) which are always special, the { and } are
reserved words and require the space after { and a newline or ; before }.
Unlike $(), the ${ ;} command substitution executes the command in
the current shell context saving the need to save and restore
changes, therefore also allowing side effects.
When trying to expand an element of a type, if the element does not exist,
ksh will look for a discipline function with that name and treat this as if
it were the ${ ;} command substitution. Thus, ${p1.len} is equivalent to
${ p1.len;} and within an arithmetic expression, p1.len will be expanded
via the new command substitution method.
The type of any variable can be obtained from the new prefix
operator @. Thus, ${@p1} will output Pt_t.
By default, each instance inherits all the discipline functions defined
by the type definition other than create. However, each instance can define
a function by the same name that will override this definition.
However, only discipline functions with the same name as those defined
by the type or the standard get, set, append, and unset disciplines
can be defined by each instance.
Each instance of the type Pt_t behaves like a compound variable except
that only the variables defined by the type can be referenced or set.
Thus, p2.x=9 is valid, but p2.z=9 is not. Unless a set discipline function
does otherwise, the value of $p1 will be expanded to the form of a compound
variable that can be used for reinput into ksh.
If the variables var1 and var2 are of the same type, then the assignment
var2=var1
will create a copy of the variable var1 into var2. This is equivalent to
eval var2="$var1"
but is faster since the variable does not need to get expanded or reparsed.
The type Pt_t can be referenced as if it were a variable using the name
.sh.type.Pt_t. To change the default point location for subsequent
instances of Pt_t, you can do
.sh.type.Pt_t=(x=5 y=12)
so that
Pt_t p3
p3.len
would be 13.
Types can be defined for simple variables as well as for compound
objects such as Pt_t. In this case, the variable named . inside
the definition refers to the real value for the variable. For example,
the type definition
typeset -T Time_t=(
integer .=0
_='%H:%M:%S'
get()
{
.sh.value=$(printf "%(${_._})T" "#$((_))" )
}
set()
{
.sh.value=$(printf "%(%#)T" "${.sh.value}")
}
)
The sub-variable name _ is reserved for data used by discipline functions
and will not be included with data written with the %B option to printf.
In this case it is used to specify a date format.
In this case
Time_t t1 t2=now
will define t1 as the time at the beginning of the epoch and t2
as the current time. Unlike the previous case, $t2 will output
the current time in the date format specified by the value t2._.
However, the value of ${t2.} will expand the instance to a form
that can be used as input to the shell.
Finally, types can be derived from an existing type. If the first
element in a type definition is named _, then the new type
consists of all the elements and discipline functions from the
type of _ extended by elements and discipline functions defined
by new type definition. For example,
typeset -T Pq_t=(
Pt_t _
float z=0.
len()
{
print -r $((sqrt(_.x*_.x + _.y*_.y + _.z*_.z)))
}
)
defines a new type Pq_t which is based on Pq_t and contains an additional
field z and a different len discipline function. It is also possible
to create a new type Pt_t based on the original Pt_t. In this case
the original Pt_t is no longer accessible.

View File

@@ -0,0 +1,297 @@
/***********************************************************************
* *
* This software is part of the ast package *
* Copyright (c) 1982-2012 AT&T Intellectual Property *
* Copyright (c) 2020-2022 Contributors to ksh 93u+m *
* and is licensed under the *
* Eclipse Public License, Version 2.0 *
* *
* A copy of the License is available at *
* https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html *
* (with md5 checksum 84283fa8859daf213bdda5a9f8d1be1d) *
* *
* David Korn <dgk@research.att.com> *
* Martijn Dekker <martijn@inlv.org> *
* *
***********************************************************************/
/*
* cd [-L] [-Pe] [dirname]
* cd [-L] [-Pe] [old] [new]
* pwd [-LP]
*
* David Korn
* AT&T Labs
* research!dgk
*
*/
#include "shopt.h"
#include "defs.h"
#include <stak.h>
#include <error.h>
#include "variables.h"
#include "path.h"
#include "name.h"
#include "builtins.h"
#include <ls.h>
#include "test.h"
/*
* Invalidate path name bindings to relative paths
*/
static void rehash(register Namval_t *np,void *data)
{
Pathcomp_t *pp = (Pathcomp_t*)np->nvalue.cp;
if(pp && *pp->name!='/')
nv_rehash(np,data);
}
int b_cd(int argc, char *argv[],Shbltin_t *context)
{
register char *dir;
Pathcomp_t *cdpath = 0;
register const char *dp;
int saverrno=0;
int rval,pflag=0,eflag=0,ret=1;
char *oldpwd;
Namval_t *opwdnod, *pwdnod;
NOT_USED(context);
while((rval = optget(argv,sh_optcd))) switch(rval)
{
case 'e':
eflag = 1;
break;
case 'L':
pflag = 0;
break;
case 'P':
pflag = 1;
break;
case ':':
if(sh_isoption(SH_RESTRICTED))
break;
errormsg(SH_DICT,2, "%s", opt_info.arg);
break;
case '?':
if(sh_isoption(SH_RESTRICTED))
break;
errormsg(SH_DICT,ERROR_usage(2), "%s", opt_info.arg);
UNREACHABLE();
}
if(pflag && eflag)
ret = 2; /* exit status is 2 if -eP are both on and chdir failed */
if(sh_isoption(SH_RESTRICTED))
{
/* restricted shells cannot change the directory */
errormsg(SH_DICT,ERROR_exit(ret),e_restricted+4);
UNREACHABLE();
}
argv += opt_info.index;
argc -= opt_info.index;
dir = argv[0];
if(error_info.errors>0 || argc>2)
{
errormsg(SH_DICT,ERROR_usage(2),"%s",optusage((char*)0));
UNREACHABLE();
}
oldpwd = path_pwd();
opwdnod = sh_scoped(OLDPWDNOD);
pwdnod = sh_scoped(PWDNOD);
if(sh.subshell)
{
/* clone $OLDPWD and $PWD into the subshell's scope */
sh_assignok(opwdnod,1);
sh_assignok(pwdnod,1);
}
if(argc==2)
dir = sh_substitute(oldpwd,dir,argv[1]);
else if(!dir)
dir = nv_getval(HOME);
else if(*dir == '-' && dir[1]==0)
dir = nv_getval(opwdnod);
if(!dir || *dir==0)
{
errormsg(SH_DICT,ERROR_exit(ret),argc==2?e_subst+4:e_direct);
UNREACHABLE();
}
/*
* If sh_subshell() in subshell.c cannot use fchdir(2) to restore the PWD using a saved file descriptor,
* we must fork any virtual subshell now to avoid the possibility of ending up in the wrong PWD on exit.
*/
if(sh.subshell && !sh.subshare)
{
#if _lib_fchdir
if(!test_inode(sh.pwd,e_dot))
#endif
sh_subfork();
}
/*
* Do $CDPATH processing, except if the path is absolute or the first component is '.' or '..'
*/
if(dir[0] != '/'
#if _WINIX
&& dir[1] != ':' /* on Windows, an initial drive letter plus ':' denotes an absolute path */
#endif /* _WINIX */
&& !(dir[0]=='.' && (dir[1]=='/' || dir[1]==0))
&& !(dir[0]=='.' && dir[1]=='.' && (dir[2]=='/' || dir[2]==0)))
{
if((dp=sh_scoped(CDPNOD)->nvalue.cp) && !(cdpath = (Pathcomp_t*)sh.cdpathlist))
{
if(cdpath=path_addpath((Pathcomp_t*)0,dp,PATH_CDPATH))
sh.cdpathlist = (void*)cdpath;
}
}
if(*dir!='/')
{
/* check for leading .. */
char *cp;
sfprintf(sh.strbuf,"%s",dir);
cp = sfstruse(sh.strbuf);
pathcanon(cp, 0);
if(cp[0]=='.' && cp[1]=='.' && (cp[2]=='/' || cp[2]==0))
{
if(!sh.strbuf2)
sh.strbuf2 = sfstropen();
sfprintf(sh.strbuf2,"%s/%s",oldpwd,cp);
dir = sfstruse(sh.strbuf2);
pathcanon(dir, 0);
}
}
rval = -1;
do
{
dp = cdpath?cdpath->name:"";
cdpath = path_nextcomp(cdpath,dir,0);
#if _WINIX
if(*stakptr(PATH_OFFSET+1)==':' && isalpha(*stakptr(PATH_OFFSET)))
{
*stakptr(PATH_OFFSET+1) = *stakptr(PATH_OFFSET);
*stakptr(PATH_OFFSET)='/';
}
#endif /* _WINIX */
if(*stakptr(PATH_OFFSET)!='/')
{
char *last=(char*)stakfreeze(1);
stakseek(PATH_OFFSET);
stakputs(oldpwd);
/* don't add '/' of oldpwd is / itself */
if(*oldpwd!='/' || oldpwd[1])
stakputc('/');
stakputs(last+PATH_OFFSET);
stakputc(0);
}
if(!pflag)
{
register char *cp;
stakseek(PATH_MAX+PATH_OFFSET);
if(*(cp=stakptr(PATH_OFFSET))=='/')
if(!pathcanon(cp,PATH_DOTDOT))
continue;
}
if((rval=chdir(path_relative(stakptr(PATH_OFFSET)))) >= 0)
goto success;
if(errno!=ENOENT && saverrno==0)
saverrno=errno;
}
while(cdpath);
if(rval<0 && *dir=='/' && *(path_relative(stakptr(PATH_OFFSET)))!='/')
rval = chdir(dir);
/* use absolute chdir() if relative chdir() fails */
if(rval<0)
{
if(saverrno)
errno = saverrno;
errormsg(SH_DICT,ERROR_system(ret),"%s:",dir);
UNREACHABLE();
}
success:
if(dir == nv_getval(opwdnod) || argc==2)
dp = dir; /* print out directory for cd - */
if(pflag)
{
dir = stakptr(PATH_OFFSET);
if (!(dir=pathcanon(dir,PATH_PHYSICAL)))
{
dir = stakptr(PATH_OFFSET);
errormsg(SH_DICT,ERROR_system(ret),"%s:",dir);
UNREACHABLE();
}
stakseek(dir-stakptr(0));
}
dir = (char*)stakfreeze(1)+PATH_OFFSET;
if(*dp && (*dp!='.'||dp[1]) && strchr(dir,'/'))
sfputr(sfstdout,dir,'\n');
nv_putval(opwdnod,oldpwd,NV_RDONLY);
free((void*)sh.pwd);
if(*dir == '/')
{
size_t len = strlen(dir);
/* delete trailing '/' */
while(--len>0 && dir[len]=='/')
dir[len] = 0;
nv_putval(pwdnod,dir,NV_RDONLY);
nv_onattr(pwdnod,NV_EXPORT);
sh.pwd = sh_strdup(dir);
}
else
{
/* pathcanon() failed to canonicalize the directory, which happens when 'cd' is invoked from a
nonexistent PWD with a relative path as the argument. Reinitialize $PWD as it will be wrong. */
sh.pwd = NIL(const char*);
path_pwd();
if(*sh.pwd != '/')
{
errormsg(SH_DICT,ERROR_system(ret),e_direct);
UNREACHABLE();
}
}
nv_scan(sh_subtracktree(1),rehash,(void*)0,NV_TAGGED,NV_TAGGED);
path_newdir(sh.pathlist);
path_newdir(sh.cdpathlist);
if(pflag && eflag)
{
/* Verify the current working directory matches $PWD */
return(!test_inode(e_dot,nv_getval(pwdnod)));
}
return(0);
}
int b_pwd(int argc, char *argv[],Shbltin_t *context)
{
register int n, flag = 0;
register char *cp;
NOT_USED(argc);
NOT_USED(context);
while((n = optget(argv,sh_optpwd))) switch(n)
{
case 'L':
flag = 0;
break;
case 'P':
flag = 1;
break;
case ':':
errormsg(SH_DICT,2, "%s", opt_info.arg);
break;
case '?':
errormsg(SH_DICT,ERROR_usage(2), "%s", opt_info.arg);
UNREACHABLE();
}
if(error_info.errors)
{
errormsg(SH_DICT,ERROR_usage(2),"%s",optusage((char*)0));
UNREACHABLE();
}
if(*(cp = path_pwd()) != '/' || !test_inode(cp,e_dot))
{
errormsg(SH_DICT,ERROR_system(1), e_pwd);
UNREACHABLE();
}
if(flag)
{
cp = strcpy(stakseek(strlen(cp)+PATH_MAX),cp);
pathcanon(cp,PATH_PHYSICAL);
}
sfputr(sfstdout,cp,'\n');
return(0);
}

View File

@@ -0,0 +1,134 @@
/***********************************************************************
* *
* This software is part of the ast package *
* Copyright (c) 1982-2012 AT&T Intellectual Property *
* Copyright (c) 2020-2022 Contributors to ksh 93u+m *
* and is licensed under the *
* Eclipse Public License, Version 2.0 *
* *
* A copy of the License is available at *
* https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html *
* (with md5 checksum 84283fa8859daf213bdda5a9f8d1be1d) *
* *
* David Korn <dgk@research.att.com> *
* Martijn Dekker <martijn@inlv.org> *
* *
***********************************************************************/
/*
* break [n]
* continue [n]
* return [n]
* exit [n]
*
* David Korn
* AT&T Labs
* dgk@research.att.com
*
*/
#include "shopt.h"
#include "defs.h"
#include <ast.h>
#include <error.h>
#include "shnodes.h"
#include "builtins.h"
/*
* return and exit
*/
#if 0
/* for the dictionary generator */
int b_exit(int n, register char *argv[],Shbltin_t *context){}
#endif
int b_return(register int n, register char *argv[],Shbltin_t *context)
{
/* 'return' outside of function, dotscript and profile behaves like 'exit' */
char do_exit = **argv=='e' || sh.fn_depth==0 && sh.dot_depth==0 && !sh_isstate(SH_PROFILE);
NOT_USED(context);
while((n = optget(argv, **argv=='e' ? sh_optexit : sh_optreturn))) switch(n)
{
case ':':
if(!strmatch(argv[opt_info.index],"[+-]+([0-9])"))
errormsg(SH_DICT,2, "%s", opt_info.arg);
goto done;
case '?':
errormsg(SH_DICT,ERROR_usage(0), "%s", opt_info.arg);
return(2);
}
done:
if(error_info.errors)
{
errormsg(SH_DICT,ERROR_usage(2),"%s",optusage((char*)0));
UNREACHABLE();
}
argv += opt_info.index;
if(*argv)
{
long l = strtol(*argv, NIL(char**), 10);
if(do_exit)
n = (int)(l & SH_EXITMASK); /* exit: apply bitmask before conversion to avoid undefined int overflow */
else if((long)(n = (int)l) != l) /* return: convert to int and check for overflow (should be safe enough) */
{
errormsg(SH_DICT,ERROR_warn(0),"%s: out of range",*argv);
n = 128; /* overflow is undefined, so use a consistent status for this */
}
}
else
{
n = sh.savexit; /* no argument: pass down $? */
if(do_exit)
n &= SH_EXITMASK;
}
((struct checkpt*)sh.jmplist)->mode = do_exit ? SH_JMPEXIT : SH_JMPFUN;
sh_exit(sh.savexit = n);
UNREACHABLE();
}
/*
* break and continue
*/
#if 0
/* for the dictionary generator */
int b_continue(int n, register char *argv[],Shbltin_t *context){}
#endif
int b_break(register int n, register char *argv[],Shbltin_t *context)
{
char *arg;
register int cont= **argv=='c';
NOT_USED(context);
while((n = optget(argv,cont?sh_optcont:sh_optbreak))) switch(n)
{
case ':':
errormsg(SH_DICT,2, "%s", opt_info.arg);
break;
case '?':
errormsg(SH_DICT,ERROR_usage(0), "%s", opt_info.arg);
return(2);
}
if(error_info.errors)
{
errormsg(SH_DICT,ERROR_usage(2),"%s",optusage((char*)0));
UNREACHABLE();
}
argv += opt_info.index;
n=1;
if(arg= *argv)
{
n = (int)strtol(arg,&arg,10);
if(n<=0 || *arg)
{
errormsg(SH_DICT,ERROR_exit(1),e_nolabels,*argv);
UNREACHABLE();
}
}
if(sh.st.loopcnt)
{
sh.st.breakcnt = n;
if(sh.st.breakcnt > sh.st.loopcnt)
sh.st.breakcnt = sh.st.loopcnt;
if(cont)
sh.st.breakcnt = -sh.st.breakcnt;
}
return(0);
}

View File

@@ -0,0 +1,324 @@
/***********************************************************************
* *
* This software is part of the ast package *
* Copyright (c) 1982-2012 AT&T Intellectual Property *
* Copyright (c) 2020-2022 Contributors to ksh 93u+m *
* and is licensed under the *
* Eclipse Public License, Version 2.0 *
* *
* A copy of the License is available at *
* https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html *
* (with md5 checksum 84283fa8859daf213bdda5a9f8d1be1d) *
* *
* David Korn <dgk@research.att.com> *
* Martijn Dekker <martijn@inlv.org> *
* *
***********************************************************************/
#include "shopt.h"
#include "defs.h"
#define ENUM_ID "enum (ksh 93u+m) 2022-03-05"
const char sh_optenum[] =
"[-?@(#)$Id: " ENUM_ID " $\n]"
"[--catalog?" ERROR_CATALOG "]"
"[+NAME?enum - create an enumeration type]"
"[+DESCRIPTION?\benum\b is a declaration command that creates one or more "
"enumeration type declaration commands named \atypename\a. Variables "
"of the created type can only store any one of the \avalue\as given. "
"For example, \benum bool=(false true)\b creates a Boolean variable "
"type of which variables may be declared like \bbool x=true y=false\b.]"
"[+?If the list of \avalue\as is omitted, then \atypename\a must name an "
"indexed array variable with at least two elements.]"
"[+?For more information, create a type, then use \atypename\a \b--man\b.]"
"[+USE IN ARITHMETIC EXPRESSIONS?When an enumeration variable is used in an "
"arithmetic expression, its value is the index into the array that "
"defined it, starting from 0. Taking the \bbool\b type from the "
"example above, if a variable of this type is used in an arithmetic "
"expression, \bfalse\b translates to 0 and \btrue\b to 1.]"
"[+?Enumeration values may also be used directly in an arithmetic expression "
"that refers to a variable of an enumeration type. "
"To continue our example, for a \bbool\b variable \bv\b, "
"\b((v==true))\b is the same as \b((v==1))\b and "
"if a variable named \btrue\b exists, it is ignored.]"
"[i:ignorecase?The values are case insensitive.]"
"\n"
"\n\atypename\a[\b=(\b \avalue\a ... \b)\b] ...\n"
"\n"
"[+EXIT STATUS]"
"{"
"[+0?Successful completion.]"
"[+>0?An error occurred.]"
"}"
"[+SEE ALSO?\bksh\b(1), \btypeset\b(1).]"
;
static const char enum_type[] =
"[-?@(#)$Id: " ENUM_ID " $\n]"
"[--catalog?" ERROR_CATALOG "]"
"[+NAME?\f?\f - create an instance of type \b\f?\f\b]"
"[+DESCRIPTION?The \b\f?\f\b declaration command creates a variable for "
"each \aname\a with enumeration type \b\f?\f\b, a type that has been "
"created with the \benum\b(1) command.]"
"[+?The variable can have one of the following values: \fvalues\f. "
"The values are \fcase\fcase sensitive. "
"If \b=\b\avalue\a is omitted, the default is \fdefault\f.]"
"[+?Within arithmetic expressions, these values translate to index numbers "
"from \b0\b (for \fdefault\f) to \flastn\f (for \flastv\f). "
"It is an error for an arithmetic expression to assign a value "
"outside of that range. Decimal fractions are ignored.]"
"[+?If no \aname\as are specified then the names and values of all "
"variables of this type are written to standard output.]"
"[+?\b\f?\f\b is built in to the shell as a declaration command so that "
"field splitting and pathname expansion are not performed on "
"the arguments. Tilde expansion occurs on \avalue\a.]"
"[r?Enables readonly. Once enabled, the value cannot be changed or unset.]"
"[a?Indexed array. Each \aname\a is converted to an indexed "
"array of type \b\f?\f\b. If a variable already exists, the current "
"value will become index \b0\b.]"
"[A?Associative array. Each \aname\a is converted to an associative "
"array of type \b\f?\f\b. If a variable already exists, the current "
"value will become subscript \b0\b.]"
"[h]:[string?Used within a type definition to provide a help string "
"for variable \aname\a. Otherwise, it is ignored.]"
"[S?Used with a type definition to indicate that the variable is shared by "
"each instance of the type. When used inside a function defined "
"with the \bfunction\b reserved word, the specified variables "
"will have function static scope. Otherwise, the variable is "
"unset prior to processing the assignment list.]"
"\n"
"\n[name[=value]...]\n"
"\n"
"[+EXIT STATUS?]{"
"[+0?Successful completion.]"
"[+>0?An error occurred.]"
"}"
"[+SEE ALSO?\benum\b(1), \btypeset\b(1)]"
;
extern const char is_spcbuiltin[];
struct Enum
{
Namfun_t hdr;
short nelem;
short iflag;
const char *values[1];
};
/*
* For range checking in arith.c
*/
short b_enum_nelem(Namfun_t *fp)
{
return(((struct Enum *)fp)->nelem);
}
static int enuminfo(Opt_t* op, Sfio_t *out, const char *str, Optdisc_t *fp)
{
Namval_t *np;
struct Enum *ep;
int n=0;
const char *v;
np = *(Namval_t**)(fp+1);
ep = (struct Enum*)np->nvfun;
if(!ep)
return(0);
if(strcmp(str,"default")==0)
sfprintf(out,"\b%s\b",ep->values[0]);
else if(strncmp(str,"last",4)==0)
{
while(ep->values[++n])
;
n--;
if(str[4]=='v')
sfprintf(out,"\b%s\b",ep->values[n]);
else
sfprintf(out,"\b%d\b",n);
}
else if(strcmp(str,"case")==0)
{
if(ep->iflag)
sfprintf(out,"not ");
}
else while(v=ep->values[n])
sfprintf(out, n++ ? ", \b%s\b" : "\b%s\b", v);
return(0);
}
static Namfun_t *clone_enum(Namval_t* np, Namval_t *mp, int flags, Namfun_t *fp)
{
struct Enum *ep, *pp=(struct Enum*)fp;
ep = sh_newof(0,struct Enum,1,pp->nelem*sizeof(char*));
memcpy((void*)ep,(void*)pp,sizeof(struct Enum)+pp->nelem*sizeof(char*));
return(&ep->hdr);
}
static void put_enum(Namval_t* np,const char *val,int flags,Namfun_t *fp)
{
struct Enum *ep = (struct Enum*)fp;
register const char *v;
unsigned short i=0;
int n;
if(!val)
{
nv_putv(np, val, flags,fp);
nv_disc(np,&ep->hdr,NV_POP);
if(!ep->hdr.nofree)
free((void*)ep);
return;
}
if(flags&NV_INTEGER)
{
nv_putv(np,val,flags,fp);
return;
}
while(v=ep->values[i])
{
if(ep->iflag)
n = strcasecmp(v,val);
else
n = strcmp(v,val);
if(n==0)
{
nv_putv(np, (char*)&i, NV_UINT16, fp);
return;
}
i++;
}
error(ERROR_exit(1), "%s: invalid value %s",nv_name(np),val);
UNREACHABLE();
}
static char* get_enum(register Namval_t* np, Namfun_t *fp)
{
static char buff[6];
struct Enum *ep = (struct Enum*)fp;
long n = nv_getn(np,fp);
if(n < ep->nelem)
return((char*)ep->values[n]);
sfsprintf(buff,sizeof(buff),"%u%c",n,0);
return(buff);
}
static Sfdouble_t get_nenum(register Namval_t* np, Namfun_t *fp)
{
return(nv_getn(np,fp));
}
const Namdisc_t ENUM_disc = { 0, put_enum, get_enum, get_nenum, 0,0,clone_enum };
#ifdef STANDALONE
static int enum_create(int argc, char** argv, Shbltin_t *context)
#else
int b_enum(int argc, char** argv, Shbltin_t *context)
#endif
{
int sz,i,n,iflag = 0;
Namval_t *np, *tp;
Namarr_t *ap;
char *cp,*sp;
struct Enum *ep;
struct {
Optdisc_t opt;
Namval_t *np;
} optdisc;
cmdinit(argc, argv, context, ERROR_CATALOG, ERROR_NOTIFY);
for (;;)
{
switch (optget(argv, sh_optenum))
{
case 'i':
iflag = 'i';
continue;
case '?':
error(ERROR_usage(2), "%s", opt_info.arg);
UNREACHABLE();
case ':':
error(2, "%s", opt_info.arg);
break;
}
break;
}
argv += opt_info.index;
if (error_info.errors || !*argv)
{
error(ERROR_USAGE|2, "%s", optusage(NiL));
return 1;
}
#ifndef STANDALONE
if(sh.subshell && !sh.subshare)
sh_subfork();
#endif
while(cp = *argv++)
{
/* Do not allow 'enum' to override special built-ins -- however, exclude
* previously created type commands from this search as that is handled elsewhere. */
if((tp=nv_search(cp,sh.bltin_tree,0)) && nv_isattr(tp,BLT_SPC) && !nv_search(cp,sh.typedict,0))
{
errormsg(SH_DICT,ERROR_exit(1),"%s:%s",cp,is_spcbuiltin);
UNREACHABLE();
}
if(!(np = nv_open(cp, (void*)0, NV_VARNAME|NV_NOADD)) || !(ap=nv_arrayptr(np)) || ap->fun || (sz=ap->nelem&(((1L<<ARRAY_BITS)-1))) < 2)
{
error(ERROR_exit(1), "%s must name an array containing at least two elements",cp);
UNREACHABLE();
}
n = staktell();
sfprintf(stkstd,"%s.%s%c",NV_CLASS,np->nvname,0);
tp = nv_open(stakptr(n), sh.var_tree, NV_VARNAME);
stakseek(n);
n = sz;
i = 0;
nv_onattr(tp, NV_UINT16);
nv_putval(tp, (char*)&i, NV_INTEGER);
nv_putsub(np, (char*)0, ARRAY_SCAN);
do
{
sz += strlen(nv_getval(np));
}
while(nv_nextsub(np));
sz += n*sizeof(char*);
ep = sh_newof(0,struct Enum,1,sz);
ep->iflag = iflag;
ep->nelem = n;
cp = (char*)&ep->values[n+1];
nv_putsub(np, (char*)0, ARRAY_SCAN);
ep->values[n] = 0;
i = 0;
do
{
ep->values[i++] = cp;
sp = nv_getval(np);
n = strlen(sp);
memcpy(cp,sp,n+1);
cp += n+1;
}
while(nv_nextsub(np));
ep->hdr.dsize = sizeof(struct Enum)+sz;
ep->hdr.disc = &ENUM_disc;
ep->hdr.type = tp;
nv_onattr(tp, NV_RDONLY);
nv_disc(tp, &ep->hdr,NV_FIRST);
memset(&optdisc,0,sizeof(optdisc));
optdisc.opt.infof = enuminfo;
optdisc.np = tp;
nv_addtype(tp, enum_type, &optdisc.opt, sizeof(optdisc));
}
return error_info.errors != 0;
}
#ifdef STANDALONE
void lib_init(int flag, void* context)
{
Namval_t *mp,*bp;
NOT_USED(context);
if(flag)
return;
bp = sh_addbuiltin("Enum", enum_create, (void*)0);
mp = nv_search("typeset",sh.bltin_tree,0);
nv_onattr(bp,nv_isattr(mp,NV_PUBLIC));
}
#endif

View File

@@ -0,0 +1,200 @@
/***********************************************************************
* *
* This software is part of the ast package *
* Copyright (c) 1982-2012 AT&T Intellectual Property *
* Copyright (c) 2020-2022 Contributors to ksh 93u+m *
* and is licensed under the *
* Eclipse Public License, Version 2.0 *
* *
* A copy of the License is available at *
* https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html *
* (with md5 checksum 84283fa8859daf213bdda5a9f8d1be1d) *
* *
* David Korn <dgk@research.att.com> *
* Martijn Dekker <martijn@inlv.org> *
* *
***********************************************************************/
/*
* getopts [-a name] optstring name [args...]
*
* David Korn
* AT&T Labs
* research!dgk
*
*/
#include "shopt.h"
#include "defs.h"
#include "variables.h"
#include <error.h>
#include <nval.h>
#include "builtins.h"
static int infof(Opt_t* op, Sfio_t* sp, const char* s, Optdisc_t* dp)
{
Stk_t *stkp = sh.stk;
#if SHOPT_NAMESPACE
if((sh.namespace && sh_fsearch(s,0)) || nv_search(s,sh.fun_tree,0))
#else
if(nv_search(s,sh.fun_tree,0))
#endif /* SHOPT_NAMESPACE */
{
int savtop = stktell(stkp);
char *savptr = stkfreeze(stkp,0);
sfputc(stkp,'$');
sfputc(stkp,'(');
sfputr(stkp,s,')');
sfputr(sp,sh_mactry(stkfreeze(stkp,1)),-1);
stkset(stkp,savptr,savtop);
}
return(1);
}
int b_getopts(int argc,char *argv[],Shbltin_t *context)
{
register char *options=error_info.context->id;
register Namval_t *np;
register int flag, mode;
char value[2], key[2];
int jmpval;
volatile int extended, r= -1;
struct checkpt buff, *pp;
Optdisc_t disc;
memset(&disc, 0, sizeof(disc));
disc.version = OPT_VERSION;
disc.infof = infof;
value[1] = 0;
key[1] = 0;
while((flag = optget(argv,sh_optgetopts))) switch(flag)
{
case 'a':
options = opt_info.arg;
break;
case ':':
errormsg(SH_DICT,2, "%s", opt_info.arg);
break;
case '?':
errormsg(SH_DICT,ERROR_usage(2), "%s", opt_info.arg);
UNREACHABLE();
}
argv += opt_info.index;
argc -= opt_info.index;
if(error_info.errors || argc<2)
{
errormsg(SH_DICT,ERROR_usage(2), "%s", optusage((char*)0));
UNREACHABLE();
}
error_info.context->flags |= ERROR_SILENT;
error_info.id = options;
options = argv[0];
np = nv_open(argv[1],sh.var_tree,NV_VARNAME);
if(argc>2)
{
argv +=1;
argc -=1;
}
else
{
argv = sh.st.dolv;
argc = sh.st.dolc;
}
opt_info.index = sh.st.optindex;
opt_info.offset = sh.st.optchar;
if(mode= (*options==':'))
options++;
extended = *options=='\n' && *(options+1)=='[' || *options=='[' && *(options+1)=='-';
sh_pushcontext(&buff,1);
jmpval = sigsetjmp(buff.buff,0);
if(jmpval)
{
sh_popcontext(&buff);
sh.st.opterror = 1;
if(r==0)
return(2);
pp = (struct checkpt*)sh.jmplist;
pp->mode = SH_JMPERREXIT;
sh_exit(2);
}
opt_info.disc = &disc;
switch(opt_info.index>=0 && opt_info.index<=argc?(opt_info.num= LONG_MIN,flag=optget(argv,options)):0)
{
case '?':
if(mode==0)
{
errormsg(SH_DICT,ERROR_usage(2), "%s", opt_info.arg);
UNREACHABLE();
}
opt_info.option[1] = '?';
/* FALLTHROUGH */
case ':':
key[0] = opt_info.option[1];
if(strmatch(opt_info.arg,"*unknown*"))
flag = '?';
if(mode)
opt_info.arg = key;
else
{
errormsg(SH_DICT,2, "%s", opt_info.arg);
opt_info.arg = 0;
flag = '?';
}
*(options = value) = flag;
sh.st.opterror = 1;
if (opt_info.offset != 0 && !argv[opt_info.index][opt_info.offset])
{
opt_info.offset = 0;
opt_info.index++;
}
break;
case 0:
if(sh.st.opterror)
{
char *com[2];
com[0] = "-?";
com[1] = 0;
flag = opt_info.index;
opt_info.index = 0;
optget(com,options);
opt_info.index = flag;
if(!mode && strchr(options,' '))
{
errormsg(SH_DICT,ERROR_usage(2), "%s", optusage((char*)0));
UNREACHABLE();
}
}
opt_info.arg = 0;
options = value;
*options = '?';
r=1;
opt_info.offset = 0;
break;
default:
options = opt_info.option + (*opt_info.option!='+');
}
if(r<0)
r = 0;
error_info.context->flags &= ~ERROR_SILENT;
sh.st.optindex = opt_info.index;
sh.st.optchar = opt_info.offset;
nv_putval(np, options, 0);
np = nv_open(nv_name(OPTARGNOD),sh.var_tree,0);
if(opt_info.num == LONG_MIN)
nv_putval(np, opt_info.arg, NV_RDONLY);
else if (opt_info.arg && opt_info.num > 0 && isalpha((char)opt_info.num) && !isdigit(opt_info.arg[0]) && opt_info.arg[0] != '-' && opt_info.arg[0] != '+')
{
key[0] = (char)opt_info.num;
key[1] = 0;
nv_putval(np, key, NV_RDONLY);
}
else if(extended)
{
Sfdouble_t d;
d = opt_info.number;
nv_putval(np, (char*)&d, NV_LDOUBLE|NV_RDONLY);
}
else
nv_putval(np, opt_info.arg, NV_RDONLY);
sh_popcontext(&buff);
opt_info.disc = 0;
return(r);
}

View File

@@ -0,0 +1,322 @@
/***********************************************************************
* *
* This software is part of the ast package *
* Copyright (c) 1982-2012 AT&T Intellectual Property *
* Copyright (c) 2020-2022 Contributors to ksh 93u+m *
* and is licensed under the *
* Eclipse Public License, Version 2.0 *
* *
* A copy of the License is available at *
* https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html *
* (with md5 checksum 84283fa8859daf213bdda5a9f8d1be1d) *
* *
* David Korn <dgk@research.att.com> *
* Martijn Dekker <martijn@inlv.org> *
* *
***********************************************************************/
#include "shopt.h"
#include "defs.h"
#include <stak.h>
#include <ls.h>
#include <error.h>
#include "variables.h"
#include "io.h"
#include "name.h"
#include "history.h"
#include "builtins.h"
#if SHOPT_HISTEXPAND
# include "edit.h"
#endif
#define HIST_RECURSE 5
static void hist_subst(const char*, int fd, char*);
#if 0
/* for the benefit of the dictionary generator */
int b_fc(int argc,char *argv[], Shbltin_t *context){}
#endif
int b_hist(int argc,char *argv[], Shbltin_t *context)
{
register History_t *hp;
register char *arg;
register int flag,fdo;
Sfio_t *outfile;
char *fname;
int range[2], incr, index2, indx= -1;
char *edit = 0; /* name of editor */
char *replace = 0; /* replace old=new */
int lflag = 0, nflag = 0, rflag = 0;
#if SHOPT_HISTEXPAND
int pflag = 0;
#endif
Histloc_t location;
NOT_USED(argc);
NOT_USED(context);
if(!sh_histinit())
{
errormsg(SH_DICT,ERROR_system(1),e_histopen);
UNREACHABLE();
}
hp = sh.hist_ptr;
while((flag = optget(argv,sh_opthist))) switch(flag)
{
case 'e':
edit = opt_info.arg;
break;
case 'n':
nflag++;
break;
case 'l':
lflag = 1;
break;
case 'r':
rflag++;
break;
case 's':
edit = "-";
break;
#if SHOPT_HISTEXPAND
case 'p':
pflag++;
break;
#endif
case 'N':
if(indx<=0)
{
if((flag = hist_max(hp) - opt_info.num-1) < 0)
flag = 1;
range[++indx] = flag;
break;
}
/* FALLTHROUGH */
case ':':
errormsg(SH_DICT,2, "%s", opt_info.arg);
break;
case '?':
errormsg(SH_DICT,ERROR_usage(2), "%s", opt_info.arg);
UNREACHABLE();
}
if(error_info.errors)
{
errormsg(SH_DICT,ERROR_usage(2),"%s",optusage((char*)0));
UNREACHABLE();
}
argv += (opt_info.index-1);
#if SHOPT_HISTEXPAND
if(pflag)
{
hist_cancel(hp);
pflag = 0;
while(arg=argv[1])
{
flag = hist_expand(arg,&replace);
if(!(flag & HIST_ERROR))
sfputr(sfstdout, replace, '\n');
else
pflag = 1;
if(replace)
free(replace);
argv++;
}
return pflag;
}
#endif
flag = indx;
while(flag<1 && (arg=argv[1]))
{
/* look for old=new argument */
if(!replace && strchr(arg+1,'='))
{
replace = arg;
argv++;
continue;
}
else if(isdigit(*arg) || *arg == '-')
{
/* see if completely numeric */
do arg++;
while(isdigit(*arg));
if(*arg==0)
{
arg = argv[1];
range[++flag] = (int)strtol(arg, (char**)0, 10);
if(*arg == '-')
range[flag] += (hist_max(hp)-1);
argv++;
continue;
}
}
/* search for last line starting with string */
location = hist_find(hp,argv[1],hist_max(hp)-1,0,-1);
if((range[++flag] = location.hist_command) < 0)
{
errormsg(SH_DICT,ERROR_exit(1),e_found,argv[1]);
UNREACHABLE();
}
argv++;
}
if(flag <0)
{
/* set default starting range */
if(lflag)
{
flag = hist_max(hp)-16;
if(flag<1)
flag = 1;
}
else
flag = hist_max(hp)-2;
range[0] = flag;
flag = 0;
}
index2 = hist_min(hp);
if(range[0]<index2)
range[0] = index2;
if(flag==0)
/* set default termination range */
range[1] = ((lflag && !edit)?hist_max(hp)-1:range[0]);
if(range[1]>=(flag=(hist_max(hp) - !lflag)))
range[1] = flag;
/* check for valid ranges */
if(range[1]<index2 || range[0]>=flag)
{
errormsg(SH_DICT,ERROR_exit(1),e_badrange,range[0],range[1]);
UNREACHABLE();
}
if(edit && *edit=='-' && range[0]!=range[1])
{
errormsg(SH_DICT,ERROR_exit(1),e_eneedsarg);
UNREACHABLE();
}
/* now list commands from range[flag] to range[1-flag] */
incr = 1;
flag = rflag>0;
if(range[1-flag] < range[flag])
incr = -1;
if(lflag)
{
outfile = sfstdout;
arg = "\n\t";
}
else
{
if(!(fname=pathtmp(NIL(char*),0,0,NIL(int*))))
{
errormsg(SH_DICT,ERROR_exit(1),e_create,"");
UNREACHABLE();
}
if((fdo=open(fname,O_CREAT|O_RDWR,S_IRUSR|S_IWUSR)) < 0)
{
errormsg(SH_DICT,ERROR_system(1),e_create,fname);
UNREACHABLE();
}
outfile= sfnew(NIL(Sfio_t*),sh.outbuff,IOBSIZE,fdo,SF_WRITE);
arg = "\n";
nflag++;
}
while(1)
{
if(nflag==0)
sfprintf(outfile,"%d\t",range[flag]);
else if(lflag)
sfputc(outfile,'\t');
hist_list(sh.hist_ptr,outfile,hist_tell(sh.hist_ptr,range[flag]),0,arg);
if(lflag)
sh_sigcheck();
if(range[flag] == range[1-flag])
break;
range[flag] += incr;
}
if(lflag)
return(0);
sfclose(outfile);
hist_eof(hp);
arg = edit;
if(!arg && !(arg=nv_getval(sh_scoped(HISTEDIT))) && !(arg=nv_getval(sh_scoped(FCEDNOD))))
{
arg = (char*)e_defedit;
if(*arg!='/')
{
errormsg(SH_DICT,ERROR_exit(1),"ed not found set FCEDIT");
UNREACHABLE();
}
}
if(*arg != '-')
{
char *com[3];
com[0] = arg;
com[1] = fname;
com[2] = 0;
error_info.errors = sh_eval(sh_sfeval(com),0);
}
fdo = sh_chkopen(fname);
unlink(fname);
free((void*)fname);
/* don't history fc itself unless forked */
error_info.flags |= ERROR_SILENT;
if(!sh_isstate(SH_FORKED))
hist_cancel(hp);
sh_onstate(SH_HISTORY);
sh_onstate(SH_VERBOSE); /* echo lines as read */
if(replace)
{
hist_subst(error_info.id,fdo,replace);
sh_close(fdo);
}
else if(error_info.errors == 0)
{
char buff[IOBSIZE+1];
Sfio_t *iop;
/* read in and run the command */
if(sh.hist_depth++ > HIST_RECURSE)
{
sh_close(fdo);
errormsg(SH_DICT,ERROR_exit(1),e_toodeep,"history");
UNREACHABLE();
}
iop = sfnew(NIL(Sfio_t*),buff,IOBSIZE,fdo,SF_READ);
sh_eval(iop,1); /* this will close fdo */
sh.hist_depth--;
}
else
{
sh_close(fdo);
if(!sh_isoption(SH_VERBOSE))
sh_offstate(SH_VERBOSE);
sh_offstate(SH_HISTORY);
}
return(sh.exitval);
}
/*
* given a file containing a command and a string of the form old=new,
* execute the command with the string old replaced by new
*/
static void hist_subst(const char *command,int fd,char *replace)
{
register char *newp=replace;
register char *sp;
register int c;
off_t size;
char *string;
while(*++newp != '='); /* skip to '=' */
if((size = lseek(fd,(off_t)0,SEEK_END)) < 0)
return;
lseek(fd,(off_t)0,SEEK_SET);
c = (int)size;
string = stakalloc(c+1);
if(read(fd,string,c)!=c)
return;
string[c] = 0;
*newp++ = 0;
if((sp=sh_substitute(string,replace,newp))==0)
{
sh_close(fd);
errormsg(SH_DICT,ERROR_exit(1),e_subst,command);
UNREACHABLE();
}
*(newp-1) = '=';
sh_eval(sfopen(NIL(Sfio_t*),sp,"s"),1);
}

View File

@@ -0,0 +1,630 @@
/***********************************************************************
* *
* This software is part of the ast package *
* Copyright (c) 1982-2012 AT&T Intellectual Property *
* Copyright (c) 2020-2022 Contributors to ksh 93u+m *
* and is licensed under the *
* Eclipse Public License, Version 2.0 *
* *
* A copy of the License is available at *
* https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html *
* (with md5 checksum 84283fa8859daf213bdda5a9f8d1be1d) *
* *
* David Korn <dgk@research.att.com> *
* Martijn Dekker <martijn@inlv.org> *
* *
***********************************************************************/
/*
* bg [job...]
* disown [job...]
* exec [-c] [-a name] [command [arg ...]]
* eval [arg...]
* fg [job...]
* jobs [-lnp] [job...]
* let expr...
* redirect [redirection...]
* source file [arg...]
* . file [arg...]
* :, true, false
* wait [job...]
* shift [n]
* times
*
* David Korn
* AT&T Labs
*
*/
#include "shopt.h"
#include "defs.h"
#include "variables.h"
#include "shnodes.h"
#include "path.h"
#include "io.h"
#include "name.h"
#include "history.h"
#include "builtins.h"
#include "jobs.h"
#include <math.h>
#include "FEATURE/locale"
#include "FEATURE/time"
#if _lib_getrusage
#include <sys/resource.h>
#else
#include <times.h>
#endif
#define DOTMAX MAXDEPTH /* maximum level of . nesting */
/*
* Handler function for nv_scan() that unsets a variable's export attribute
*/
static void noexport(register Namval_t* np, void *data)
{
NOT_USED(data);
nv_offattr(np,NV_EXPORT);
}
/*
* 'exec' special builtin and 'redirect' builtin
*/
#if 0
/* for the dictionary generator */
int b_redirect(int argc,char *argv[],Shbltin_t *context){}
#endif
int b_exec(int argc,char *argv[], Shbltin_t *context)
{
register int n;
struct checkpt *pp;
const char *pname;
int clear = 0;
char *arg0 = 0;
NOT_USED(argc);
NOT_USED(context);
sh.st.ioset = 0;
while (n = optget(argv, *argv[0]=='r' ? sh_optredirect : sh_optexec)) switch (n)
{
case 'a':
arg0 = opt_info.arg;
break;
case 'c':
clear=1;
break;
case ':':
errormsg(SH_DICT,2, "%s", opt_info.arg);
break;
case '?':
errormsg(SH_DICT,ERROR_usage(0), "%s", opt_info.arg);
return(2);
}
if(error_info.errors)
{
errormsg(SH_DICT,ERROR_usage(2),"%s",optusage((char*)0));
UNREACHABLE();
}
if(*argv[0]=='r' && argv[opt_info.index]) /* 'redirect' supports no args */
{
errormsg(SH_DICT,ERROR_exit(2),"%s: %s",e_badsyntax,argv[opt_info.index]);
UNREACHABLE();
}
argv += opt_info.index;
if(!*argv)
return(0);
/* from here on, it's 'exec' with args, so we're replacing the shell */
if(sh_isoption(SH_RESTRICTED))
{
errormsg(SH_DICT,ERROR_exit(1),e_restricted,argv[0]);
UNREACHABLE();
}
else
{
register struct argnod *arg=sh.envlist;
register Namval_t* np;
register char *cp;
if(sh.subshell && !sh.subshare)
sh_subfork();
if(clear)
nv_scan(sh.var_tree,noexport,0,NV_EXPORT,NV_EXPORT);
while(arg)
{
if((cp=strchr(arg->argval,'=')) &&
(*cp=0,np=nv_search(arg->argval,sh.var_tree,0)))
{
nv_onattr(np,NV_EXPORT);
env_change();
}
if(cp)
*cp = '=';
arg=arg->argnxt.ap;
}
pname = argv[0];
if(arg0)
argv[0] = arg0;
#ifdef JOBS
if(job_close() < 0)
return(1);
#endif /* JOBS */
/* if the main shell is about to be replaced, decrease SHLVL to cancel out a subsequent increase */
if(!sh.realsubshell)
(*SHLVL->nvalue.ip)--;
/* force bad exec to terminate shell */
pp = (struct checkpt*)sh.jmplist;
pp->mode = SH_JMPEXIT;
sh_sigreset(2);
sh_freeup();
path_exec(pname,argv,NIL(struct argnod*));
}
return(1);
}
int b_let(int argc,char *argv[],Shbltin_t *context)
{
register int r;
register char *arg;
NOT_USED(argc);
NOT_USED(context);
while (r = optget(argv,sh_optlet)) switch (r)
{
case ':':
errormsg(SH_DICT,2, "%s", opt_info.arg);
break;
case '?':
errormsg(SH_DICT,ERROR_usage(2), "%s", opt_info.arg);
UNREACHABLE();
}
argv += opt_info.index;
if(error_info.errors || !*argv)
{
errormsg(SH_DICT,ERROR_usage(2),"%s",optusage((char*)0));
UNREACHABLE();
}
while(arg= *argv++)
r = !sh_arith(arg);
return(r);
}
int b_eval(int argc,char *argv[], Shbltin_t *context)
{
register int r;
NOT_USED(argc);
NOT_USED(context);
while (r = optget(argv,sh_opteval)) switch (r)
{
case ':':
errormsg(SH_DICT,2, "%s", opt_info.arg);
break;
case '?':
errormsg(SH_DICT,ERROR_usage(0), "%s",opt_info.arg);
return(2);
}
if(error_info.errors)
{
errormsg(SH_DICT,ERROR_usage(2),"%s",optusage((char*)0));
UNREACHABLE();
}
argv += opt_info.index;
if(*argv && **argv)
sh_eval(sh_sfeval(argv),0);
return(sh.exitval);
}
#if 0
/* for the dictionary generator */
int b_source(register int n,char *argv[],Shbltin_t *context){}
#endif
int b_dot_cmd(register int n,char *argv[],Shbltin_t *context)
{
register char *script;
register Namval_t *np;
register int jmpval;
struct sh_scoped savst, *prevscope = sh.st.self;
char *filename=0, *buffer=0, *tofree;
int fd;
struct dolnod *saveargfor;
volatile struct dolnod *argsave=0;
struct checkpt buff;
Sfio_t *iop=0;
NOT_USED(context);
while (n = optget(argv,sh_optdot)) switch (n)
{
case ':':
errormsg(SH_DICT,2, "%s", opt_info.arg);
break;
case '?':
errormsg(SH_DICT,ERROR_usage(0), "%s",opt_info.arg);
return(2);
}
argv += opt_info.index;
script = *argv;
if(error_info.errors || !script)
{
errormsg(SH_DICT,ERROR_usage(2),"%s",optusage((char*)0));
UNREACHABLE();
}
if(sh.dot_depth >= DOTMAX)
{
errormsg(SH_DICT,ERROR_exit(1),e_toodeep,script);
UNREACHABLE();
}
if(!(np=sh.posix_fun))
{
/* check for KornShell style function first */
np = nv_search(script,sh.fun_tree,0);
if(np && is_afunction(np) && !nv_isattr(np,NV_FPOSIX) && !(sh_isoption(SH_POSIX) && sh.bltindata.bnode==SYSDOT))
{
if(!np->nvalue.ip)
{
path_search(script,NIL(Pathcomp_t**),0);
if(np->nvalue.ip)
{
if(nv_isattr(np,NV_FPOSIX))
np = 0;
}
else
{
errormsg(SH_DICT,ERROR_exit(1),e_found,script);
UNREACHABLE();
}
}
}
else
np = 0;
if(!np)
{
if((fd=path_open(script,path_get(script))) < 0)
{
errormsg(SH_DICT,ERROR_system(1),e_open,script);
UNREACHABLE();
}
filename = path_fullname(stkptr(sh.stk,PATH_OFFSET));
}
}
*prevscope = sh.st;
sh.st.lineno = np?((struct functnod*)nv_funtree(np))->functline:1;
sh.st.save_tree = sh.var_tree;
if(filename)
{
sh.st.filename = filename;
sh.st.lineno = 1;
}
sh.st.prevst = prevscope;
sh.st.self = &savst;
sh.topscope = (Shscope_t*)sh.st.self;
prevscope->save_tree = sh.var_tree;
tofree = sh.st.filename;
if(np)
sh.st.filename = np->nvalue.rp->fname;
nv_putval(SH_PATHNAMENOD, sh.st.filename ,NV_NOFREE);
sh.posix_fun = 0;
if(np || argv[1])
argsave = sh_argnew(argv,&saveargfor);
sh_pushcontext(&buff,SH_JMPDOT);
errorpush(&buff.err,0);
error_info.id = argv[0];
jmpval = sigsetjmp(buff.buff,0);
if(jmpval == 0)
{
sh.dot_depth++;
update_sh_level();
if(np)
sh_exec((Shnode_t*)(nv_funtree(np)),sh_isstate(SH_ERREXIT));
else
{
buffer = sh_malloc(IOBSIZE+1);
iop = sfnew(NIL(Sfio_t*),buffer,IOBSIZE,fd,SF_READ);
sh_offstate(SH_NOFORK);
sh_eval(iop,sh_isstate(SH_PROFILE)?SH_FUNEVAL:0);
}
}
sh_popcontext(&buff);
if(buffer)
free(buffer);
if(!np)
free(tofree);
sh.dot_depth--;
update_sh_level();
if((np || argv[1]) && jmpval!=SH_JMPSCRIPT)
sh_argreset((struct dolnod*)argsave,saveargfor);
else
{
prevscope->dolc = sh.st.dolc;
prevscope->dolv = sh.st.dolv;
}
if (sh.st.self != &savst)
*sh.st.self = sh.st;
/* only restore the top Shscope_t portion for POSIX functions */
memcpy((void*)&sh.st, (void*)prevscope, sizeof(Shscope_t));
sh.topscope = (Shscope_t*)prevscope;
nv_putval(SH_PATHNAMENOD, sh.st.filename ,NV_NOFREE);
if(jmpval && jmpval!=SH_JMPFUN)
siglongjmp(*sh.jmplist,jmpval);
return(sh.exitval);
}
/*
* null, true command
*/
int b_true(int argc,register char *argv[],Shbltin_t *context)
{
NOT_USED(argc);
NOT_USED(argv[0]);
NOT_USED(context);
return(0);
}
/*
* false command
*/
int b_false(int argc,register char *argv[], Shbltin_t *context)
{
NOT_USED(argc);
NOT_USED(argv[0]);
NOT_USED(context);
return(1);
}
int b_shift(register int n, register char *argv[], Shbltin_t *context)
{
register char *arg;
NOT_USED(context);
while((n = optget(argv,sh_optshift))) switch(n)
{
case ':':
errormsg(SH_DICT,2, "%s", opt_info.arg);
break;
case '?':
errormsg(SH_DICT,ERROR_usage(0), "%s",opt_info.arg);
return(2);
}
if(error_info.errors)
{
errormsg(SH_DICT,ERROR_usage(2),"%s",optusage((char*)0));
UNREACHABLE();
}
argv += opt_info.index;
n = ((arg= *argv)?(int)sh_arith(arg):1);
if(n < 0 || sh.st.dolc < n)
{
errormsg(SH_DICT,ERROR_exit(1),e_number,arg);
UNREACHABLE();
}
else
{
sh.st.dolv += n;
sh.st.dolc -= n;
}
return(0);
}
int b_wait(int n,register char *argv[],Shbltin_t *context)
{
NOT_USED(context);
while((n = optget(argv,sh_optwait))) switch(n)
{
case ':':
errormsg(SH_DICT,2, "%s", opt_info.arg);
break;
case '?':
errormsg(SH_DICT,ERROR_usage(2), "%s",opt_info.arg);
UNREACHABLE();
}
if(error_info.errors)
{
errormsg(SH_DICT,ERROR_usage(2),"%s",optusage((char*)0));
UNREACHABLE();
}
argv += opt_info.index;
job_bwait(argv);
return(sh.exitval);
}
#ifdef JOBS
# if 0
/* for the dictionary generator */
int b_fg(int n,char *argv[],Shbltin_t *context){}
int b_disown(int n,char *argv[],Shbltin_t *context){}
# endif
int b_bg(register int n,register char *argv[],Shbltin_t *context)
{
register int flag = **argv;
register const char *optstr = sh_optbg;
NOT_USED(context);
if(*argv[0]=='f')
optstr = sh_optfg;
else if(*argv[0]=='d')
optstr = sh_optdisown;
while((n = optget(argv,optstr))) switch(n)
{
case ':':
errormsg(SH_DICT,2, "%s", opt_info.arg);
break;
case '?':
errormsg(SH_DICT,ERROR_usage(2), "%s",opt_info.arg);
UNREACHABLE();
}
if(error_info.errors)
{
errormsg(SH_DICT,ERROR_usage(2),"%s",optusage((char*)0));
UNREACHABLE();
}
argv += opt_info.index;
if(!sh_isstate(SH_MONITOR))
{
errormsg(SH_DICT,ERROR_exit(1),e_no_jctl);
UNREACHABLE();
}
if(flag=='d' && *argv==0)
argv = (char**)0;
if(job_walk(sfstdout,job_switch,flag,argv))
{
errormsg(SH_DICT,ERROR_exit(1),e_no_job);
UNREACHABLE();
}
return(sh.exitval);
}
int b_jobs(register int n,char *argv[],Shbltin_t *context)
{
register int flag = 0;
NOT_USED(context);
while((n = optget(argv,sh_optjobs))) switch(n)
{
case 'l':
flag = JOB_LFLAG;
break;
case 'n':
flag = JOB_NFLAG;
break;
case 'p':
flag = JOB_PFLAG;
break;
case ':':
errormsg(SH_DICT,2, "%s", opt_info.arg);
break;
case '?':
errormsg(SH_DICT,ERROR_usage(2), "%s",opt_info.arg);
UNREACHABLE();
}
argv += opt_info.index;
if(error_info.errors)
{
errormsg(SH_DICT,ERROR_usage(2),"%s",optusage((char*)0));
UNREACHABLE();
}
if(*argv==0)
argv = (char**)0;
if(job_walk(sfstdout,job_list,flag,argv))
{
errormsg(SH_DICT,ERROR_exit(1),e_no_job);
UNREACHABLE();
}
job_wait((pid_t)0);
return(sh.exitval);
}
#endif
/*
* times command
*/
static void print_times(struct timeval utime, struct timeval stime)
{
int ut_min = utime.tv_sec / 60;
int ut_sec = utime.tv_sec % 60;
int ut_ms = utime.tv_usec / 1000;
int st_min = stime.tv_sec / 60;
int st_sec = stime.tv_sec % 60;
int st_ms = stime.tv_usec / 1000;
sfprintf(sfstdout, sh_isoption(SH_POSIX) ? "%dm%d%c%03ds %dm%d%c%03ds\n" : "%dm%02d%c%03ds %dm%02d%c%03ds\n",
ut_min, ut_sec, sh.radixpoint, ut_ms, st_min, st_sec, sh.radixpoint, st_ms);
}
#if _lib_getrusage
/* getrusage tends to have higher precision */
static void print_cpu_times(void)
{
struct rusage usage;
/* Print the time (user & system) consumed by the shell. */
getrusage(RUSAGE_SELF, &usage);
print_times(usage.ru_utime, usage.ru_stime);
/* Print the time (user & system) consumed by the child processes of the shell. */
getrusage(RUSAGE_CHILDREN, &usage);
print_times(usage.ru_utime, usage.ru_stime);
}
#else /* _lib_getrusage */
static void print_cpu_times(void)
{
struct timeval utime, stime;
double dtime;
int clk_tck = sh.lim.clk_tck;
struct tms cpu_times;
times(&cpu_times);
/* Print the time (user & system) consumed by the shell. */
dtime = (double)cpu_times.tms_utime / clk_tck;
utime.tv_sec = dtime / 60;
utime.tv_usec = 1000000 * (dtime - utime.tv_sec);
dtime = (double)cpu_times.tms_stime / clk_tck;
stime.tv_sec = dtime / 60;
stime.tv_usec = 1000000 * (dtime - utime.tv_sec);
print_times(utime, stime);
/* Print the time (user & system) consumed by the child processes of the shell. */
dtime = (double)cpu_times.tms_cutime / clk_tck;
utime.tv_sec = dtime / 60;
utime.tv_usec = 1000000 * (dtime - utime.tv_sec);
dtime = (double)cpu_times.tms_cstime / clk_tck;
stime.tv_sec = dtime / 60;
stime.tv_usec = 1000000 * (dtime - utime.tv_sec);
print_times(utime, stime);
}
#endif /* _lib_getrusage */
int b_times(int argc, char *argv[], Shbltin_t *context)
{
NOT_USED(context);
/* No options or operands are supported, except --man, etc. */
if (argc = optget(argv, sh_opttimes)) switch (argc)
{
case ':':
errormsg(SH_DICT, 2, "%s", opt_info.arg);
errormsg(SH_DICT, ERROR_usage(2), "%s", optusage((char*)0));
UNREACHABLE();
default:
errormsg(SH_DICT, ERROR_usage(0), "%s", opt_info.arg);
return(2);
}
if (argv[opt_info.index])
{
errormsg(SH_DICT, ERROR_exit(2), e_toomanyops);
UNREACHABLE();
}
/* Get & print the times */
print_cpu_times();
return(0);
}
#ifdef _cmd_universe
/*
* There are several universe styles that are masked by the getuniv(),
* setuniv() calls.
*/
int b_universe(int argc, char *argv[],Shbltin_t *context)
{
register char *arg;
register int n;
NOT_USED(context);
while((n = optget(argv,sh_optuniverse))) switch(n)
{
case ':':
errormsg(SH_DICT,2, "%s", opt_info.arg);
break;
case '?':
errormsg(SH_DICT,ERROR_usage(2), "%s",opt_info.arg);
UNREACHABLE();
}
argv += opt_info.index;
argc -= opt_info.index;
if(error_info.errors || argc>1)
{
errormsg(SH_DICT,ERROR_usage(2),"%s",optusage((char*)0));
UNREACHABLE();
}
if(arg = argv[0])
{
if(!astconf("UNIVERSE",0,arg))
{
errormsg(SH_DICT,ERROR_exit(1), e_badname,arg);
UNREACHABLE();
}
}
else
{
if(!(arg=astconf("UNIVERSE",0,0)))
{
errormsg(SH_DICT,ERROR_exit(1),e_nouniverse);
UNREACHABLE();
}
else
sfputr(sfstdout,arg,'\n');
}
return(0);
}
#endif /* cmd_universe */

View File

@@ -0,0 +1,499 @@
/***********************************************************************
* *
* This software is part of the ast package *
* Copyright (c) 1982-2012 AT&T Intellectual Property *
* Copyright (c) 2020-2022 Contributors to ksh 93u+m *
* and is licensed under the *
* Eclipse Public License, Version 2.0 *
* *
* A copy of the License is available at *
* https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html *
* (with md5 checksum 84283fa8859daf213bdda5a9f8d1be1d) *
* *
* David Korn <dgk@research.att.com> *
* Martijn Dekker <martijn@inlv.org> *
* *
***********************************************************************/
/*
* mkservice varname pathname
* eloop [-t timeout]
* Written by David Korn
* AT&T Labs
*/
#include "shopt.h"
#include "defs.h"
#if !SHOPT_MKSERVICE
NoN(mkservice)
#else
static const char mkservice_usage[] =
"[-?\n@(#)$Id: mkservice (AT&T Research) 2001-06-13 $\n]"
"[--catalog?" SH_DICT "]"
"[+NAME? mkservice - create a shell server ]"
"[+DESCRIPTION?\bmkservice\b creates a tcp or udp server that is "
"implemented by shell functions.]"
"[+?The \aservice_path\a must be of the form \b/dev/tcp/localhost/\b\aportno\a "
"or \b/dev/udp/localhost/\b\aportno\a depending on whether the "
"\btcp\b or \budp\b protocol is used. \aportno\a is the port "
"number that the service will use.]"
"[+?The shell variable \avarname\a is associated with the service. This "
"variable can have subvariables that keeps the state of all "
"active connections. The functions \avarname\a\b.accept\b, "
"\avarname\a\b.action\b and \avarname\a\b.close\b implement the "
"service as follows:]{"
"[+accept?This function is invoked when a client tries to connect "
"to the service. It is called with an argument which "
"is the file descriptor number associated with the "
"accepted connection. If the function returns a non-zero "
"value, this connection will be closed.]"
"[+action?This function is invoked when there is data waiting "
"to be read from one of the active connections. It is "
"called with the file descriptor number that has data "
"to be read. If the function returns a non-zero "
"value, this connection will be closed.]"
"[+close?This function is invoked when the connection is closed.]"
"}"
"[+?If \avarname\a is unset, then all active connection, and the service "
"itself will be closed.]"
""
"\n"
"\nvarname service_path\n"
"\n"
"[+EXIT STATUS?]{"
"[+0?Success.]"
"[+>0?An error occurred.]"
"}"
"[+SEE ALSO?\beloop\b(1)]"
;
static const char eloop_usage[] =
"[-?\n@(#)$Id: eloop (AT&T Research) 2001-06-13 $\n]"
"[--catalog?" SH_DICT "]"
"[+NAME? eloop - process event loop]"
"[+DESCRIPTION?\beloop\b causes the shell to block waiting for events "
"to process. By default, \beloop\b does not return.]"
"[t]#[timeout?\atimeout\a is the number of milliseconds to wait "
"without receiving any events to process.]"
"\n"
"\n\n"
"\n"
"[+EXIT STATUS?If no timeout is specified, \beloop\b will not return "
"unless interrupted. Otherwise]{"
"[+0?The specified timeout interval occurred.]"
"[+>0?An error occurred.]"
"}"
"[+SEE ALSO?\bmkservice\b(1)]"
;
#include <cmd.h>
#include <error.h>
#include <nval.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define ACCEPT 0
#define ACTION 1
#define CLOSE 2
#ifndef O_SERVICE
# define O_SERVICE O_NOCTTY
#endif
static const char* disctab[] =
{
"accept",
"action",
"close",
0
};
typedef struct Service_s Service_t;
struct Service_s
{
Namfun_t fun;
int fd;
int refcount;
int (*acceptf)(Service_t*,int);
int (*actionf)(Service_t*,int,int);
int (*errorf)(Service_t*,int,const char*, ...);
void *context;
Namval_t* node;
Namval_t* disc[elementsof(disctab)-1];
};
static int *file_list;
static Sfio_t **poll_list;
static Service_t **service_list;
static int npoll;
static int nready;
static int ready;
static int (*covered_fdnotify)(int, int);
static int fdclose(Service_t *sp, register int fd)
{
register int i;
service_list[fd] = 0;
if(sp->fd==fd)
sp->fd = -1;
for(i=0; i < npoll; i++)
{
if(file_list[i]==fd)
{
file_list[i] = file_list[npoll--];
if(sp->actionf)
(*sp->actionf)(sp, fd, 1);
return(1);
}
}
return(0);
}
static int fdnotify(int fd1, int fd2)
{
Service_t *sp;
if (covered_fdnotify)
(*covered_fdnotify)(fd1, fd2);
if(fd2!=SH_FDCLOSE)
{
register int i;
service_list[fd2] = service_list[fd1];
service_list[fd1] = 0;
for(i=0; i < npoll; i++)
{
if(file_list[i]==fd1)
{
file_list[i] = fd2;
return(0);
}
}
}
else if(sp = service_list[fd1])
{
fdclose(sp,fd1);
if(--sp->refcount==0)
nv_unset(sp->node);
}
return(0);
}
static void process_stream(Sfio_t* iop)
{
int r=0, fd = sffileno(iop);
Service_t * sp = service_list[fd];
if(fd==sp->fd) /* connection socket */
{
struct sockaddr addr;
socklen_t addrlen = sizeof(addr);
fd = accept(fd, &addr, &addrlen);
service_list[fd] = sp;
sp->refcount++;
file_list[npoll++] = fd;
if(fd>=0)
{
if(sp->acceptf)
r = (*sp->acceptf)(sp,fd);
}
}
else if(sp->actionf)
{
service_list[fd] = 0;
r = (*sp->actionf)(sp, fd, 0);
service_list[fd] = sp;
if(r<0)
close(fd);
}
}
static int waitnotify(int fd, long timeout, int rw)
{
Sfio_t *special=0, **pstream;
register int i;
if (fd >= 0)
special = sh_fd2sfio(fd);
while(1)
{
pstream = poll_list;
while(ready < nready)
process_stream(pstream[ready++]);
if(special)
*pstream++ = special;
for(i=0; i < npoll; i++)
{
if(service_list[file_list[i]])
*pstream++ = sh_fd2sfio(file_list[i]);
}
for(i=0; i < pstream-poll_list; i++)
sfset(poll_list[i],SF_WRITE,0);
nready = ready = 0;
errno = 0;
#ifdef DEBUG
sfprintf(sfstderr,"before poll npoll=%d",pstream-poll_list);
for(i=0; i < pstream-poll_list; i++)
sfprintf(sfstderr," %d",sffileno(poll_list[i]));
sfputc(sfstderr,'\n');
#endif
nready = sfpoll(poll_list,pstream-poll_list,timeout);
#ifdef DEBUG
sfprintf(sfstderr,"after poll nready=%d",nready);
for(i=0; i < nready; i++)
sfprintf(sfstderr," %d",sffileno(poll_list[i]));
sfputc(sfstderr,'\n');
#endif
for(i=0; i < pstream-poll_list; i++)
sfset(poll_list[i],SF_WRITE,1);
if(nready<=0)
return(errno? -1: 0);
if(special && poll_list[0]==special)
{
ready = 1;
return(fd);
}
}
}
static int service_init(void)
{
int n = 20;
file_list = (int*)sh_newof(NULL,short,n,0);
poll_list = sh_newof(NULL,Sfio_t*,n,0);
service_list = sh_newof(NULL,Service_t*,n,0);
covered_fdnotify = sh_fdnotify(fdnotify);
sh_waitnotify(waitnotify);
return(1);
}
void service_add(Service_t *sp)
{
static int init;
if (!init)
init = service_init();
service_list[sp->fd] = sp;
file_list[npoll++] = sp->fd;
}
static int Accept(register Service_t *sp, int accept_fd)
{
register Namval_t* nq = sp->disc[ACCEPT];
int fd;
fd = fcntl(accept_fd, F_DUPFD, 10);
if (fd >= 0)
{
close(accept_fd);
if (nq)
{
char* av[3];
char buff[20];
av[1] = buff;
av[2] = 0;
sfsprintf(buff, sizeof(buff), "%d", fd);
if (sh_fun(nq, sp->node, av))
{
close(fd);
return -1;
}
}
}
sfsync(NiL);
return fd;
}
static int Action(Service_t *sp, int fd, int close)
{
register Namval_t* nq;
int r=0;
if(close)
nq = sp->disc[CLOSE];
else
nq = sp->disc[ACTION];
if (nq)
{
char* av[3];
char buff[20];
av[1] = buff;
av[2] = 0;
sfsprintf(buff, sizeof(buff), "%d", fd);
r=sh_fun(nq, sp->node, av);
}
sfsync(NiL);
return r > 0 ? -1 : 1;
}
static int Error(Service_t *sp, int level, const char* arg, ...)
{
va_list ap;
va_start(ap, arg);
if(sp->node)
nv_unset(sp->node);
free((void*)sp);
errorv(NiL, ERROR_exit(1), ap);
va_end(ap);
return 0;
}
static char* setdisc(Namval_t* np, const char* event, Namval_t* action, Namfun_t* fp)
{
register Service_t* sp = (Service_t*)fp;
register const char* cp;
register int i;
register int n = strlen(event) - 1;
register Namval_t* nq;
for (i = 0; cp = disctab[i]; i++)
{
if (strncmp(event, cp, n))
continue;
if (action == np)
action = sp->disc[i];
else
{
if (nq = sp->disc[i])
free((void*)nq);
if (action)
sp->disc[i] = action;
else
sp->disc[i] = 0;
}
return action ? (char*)action : "";
}
/* try the next level */
return nv_setdisc(np, event, action, fp);
}
static void putval(Namval_t* np, const char* val, int flag, Namfun_t* fp)
{
register Service_t* sp = (Service_t*)fp;
if (!val)
fp = nv_stack(np, NiL);
nv_putv(np, val, flag, fp);
if (!val)
{
register int i;
for(i=0; i< sh.lim.open_max; i++)
{
if(service_list[i]==sp)
{
close(i);
if(--sp->refcount<=0)
break;
}
}
free((void*)fp);
return;
}
}
static const Namdisc_t servdisc =
{
sizeof(Service_t),
putval,
0,
0,
setdisc
};
int b_mkservice(int argc, char** argv, Shbltin_t *context)
{
register char* var;
register char* path;
register Namval_t* np;
register Service_t* sp;
register int fd;
NOT_USED(argc);
for (;;)
{
switch (optget(argv, mkservice_usage))
{
case 0:
break;
case ':':
error(2, opt_info.arg);
continue;
case '?':
error(ERROR_usage(2), opt_info.arg);
UNREACHABLE();
}
break;
}
argv += opt_info.index;
if (error_info.errors || !(var = *argv++) || !(path = *argv++) || *argv)
{
error(ERROR_usage(2), optusage(NiL));
UNREACHABLE();
}
sp = sh_newof(0, Service_t, 1, 0);
sp->acceptf = Accept;
sp->actionf = Action;
sp->errorf = Error;
sp->refcount = 1;
sp->context = context;
sp->node = 0;
sp->fun.disc = &servdisc;
if((fd = sh_open(path, O_SERVICE|O_RDWR))<=0)
{
free((void*)sp);
error(ERROR_exit(1), "%s: cannot start service", path);
UNREACHABLE();
}
if((sp->fd = fcntl(fd, F_DUPFD, 10))>=10)
close(fd);
else
sp->fd = fd;
np = nv_open(var,sh.var_tree,NV_ARRAY|NV_VARNAME);
sp->node = np;
nv_putval(np, path, 0);
nv_stack(np, (Namfun_t*)sp);
service_add(sp);
return(0);
}
int b_eloop(int argc, char** argv, Shbltin_t *context)
{
register long timeout = -1;
NOT_USED(argc);
NOT_USED(context);
for (;;)
{
switch (optget(argv, eloop_usage))
{
case 0:
break;
case 't':
timeout = opt_info.num;
continue;
case ':':
error(2, opt_info.arg);
continue;
case '?':
error(ERROR_usage(2), opt_info.arg);
UNREACHABLE();
}
break;
}
argv += opt_info.index;
if (error_info.errors || *argv)
{
error(ERROR_usage(2), optusage(NiL));
UNREACHABLE();
}
while(1)
{
if(waitnotify(-1, timeout, 0)==0)
break;
sfprintf(sfstderr,"interrupted\n");
}
return(errno != 0);
}
#endif /* SHOPT_MKSERVICE */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,833 @@
/***********************************************************************
* *
* This software is part of the ast package *
* Copyright (c) 1982-2012 AT&T Intellectual Property *
* Copyright (c) 2020-2022 Contributors to ksh 93u+m *
* and is licensed under the *
* Eclipse Public License, Version 2.0 *
* *
* A copy of the License is available at *
* https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html *
* (with md5 checksum 84283fa8859daf213bdda5a9f8d1be1d) *
* *
* David Korn <dgk@research.att.com> *
* Martijn Dekker <martijn@inlv.org> *
* Johnothan King <johnothanking@protonmail.com> *
* *
***********************************************************************/
/*
* read [-AaCprsSv] [-d delim] [-u fd] [-t timeout] [-n count] [-N count] [var?prompt] [var ...]
*
* David Korn
* AT&T Labs
*
*/
#include "shopt.h"
#include <ast.h>
#include <error.h>
#include "defs.h"
#include "variables.h"
#include "lexstates.h"
#include "io.h"
#include "name.h"
#include "builtins.h"
#include "history.h"
#include "terminal.h"
#include "edit.h"
#define R_FLAG 1 /* raw mode */
#define S_FLAG 2 /* save in history file */
#define A_FLAG 4 /* read into array */
#define N_FLAG 8 /* fixed size read at most */
#define NN_FLAG 0x10 /* fixed size read exact */
#define V_FLAG 0x20 /* use default value */
#define C_FLAG 0x40 /* read into compound variable */
#define D_FLAG 8 /* must be number of bits for all flags */
#define SS_FLAG 0x80 /* read .csv format file */
struct read_save
{
char **argv;
char *prompt;
int fd;
int plen;
int flags;
ssize_t len;
long timeout;
};
int b_read(int argc,char *argv[], Shbltin_t *context)
{
Sfdouble_t sec;
char *prompt;
register int r, flags=0, fd=0;
ssize_t len=0;
long timeout = 1000*sh.st.tmout;
int save_prompt, fixargs=context->invariant;
struct read_save *rp;
static char default_prompt[3] = {ESC,ESC};
rp = (struct read_save*)(context->data);
if(argc==0)
{
if(rp)
free((void*)rp);
return(0);
}
if(rp)
{
flags = rp->flags;
timeout = rp->timeout;
fd = rp->fd;
argv = rp->argv;
prompt = rp->prompt;
r = rp->plen;
goto bypass;
}
while((r = optget(argv,sh_optread))) switch(r)
{
case 'A':
flags |= A_FLAG;
break;
case 'C':
flags |= C_FLAG;
break;
case 't':
sec = sh_strnum(opt_info.arg, (char**)0,1);
timeout = sec ? 1000*sec : 1;
break;
case 'd':
if(opt_info.arg && *opt_info.arg!='\n')
{
char *cp = opt_info.arg;
flags &= ((1<<D_FLAG+1)-1);
flags |= (mbchar(cp)<<D_FLAG+1) | (1<<D_FLAG);
}
break;
case 'p':
coprocess:
if((fd = sh.cpipe[0])<=0)
{
errormsg(SH_DICT,ERROR_exit(1),e_query);
UNREACHABLE();
}
break;
case 'n': case 'N':
flags &= ((1<<D_FLAG)-1);
flags |= (r=='n'?N_FLAG:NN_FLAG);
len = opt_info.num;
break;
case 'r':
flags |= R_FLAG;
break;
case 's':
/* save in history file */
flags |= S_FLAG;
break;
case 'S':
flags |= SS_FLAG;
break;
case 'u':
if(opt_info.arg[0]=='p' && opt_info.arg[1]==0)
goto coprocess;
fd = (int)strtol(opt_info.arg,&opt_info.arg,10);
if(*opt_info.arg || !sh_iovalidfd(fd) || sh_inuse(fd))
fd = -1;
break;
case 'v':
flags |= V_FLAG;
break;
case ':':
errormsg(SH_DICT,2, "%s", opt_info.arg);
break;
case '?':
errormsg(SH_DICT,ERROR_usage(2), "%s", opt_info.arg);
UNREACHABLE();
}
argv += opt_info.index;
if(error_info.errors)
{
errormsg(SH_DICT,ERROR_usage(2), "%s", optusage((char*)0));
UNREACHABLE();
}
if(!((r=sh.fdstatus[fd])&IOREAD) || !(r&(IOSEEK|IONOSEEK)))
r = sh_iocheckfd(fd);
if(fd<0 || !(r&IOREAD))
{
errormsg(SH_DICT,ERROR_system(1),e_file+4);
UNREACHABLE();
}
/* look for prompt */
if((prompt = *argv) && (prompt=strchr(prompt,'?')) && (r&IOTTY))
r = strlen(prompt++);
else
r = 0;
if(argc==fixargs)
{
rp = sh_newof(NIL(struct read_save*),struct read_save,1,0);
context->data = (void*)rp;
rp->fd = fd;
rp->flags = flags;
rp->timeout = timeout;
rp->argv = argv;
rp->prompt = prompt;
rp->plen = r;
rp->len = len;
}
bypass:
sh.prompt = default_prompt;
if(r && (sh.prompt=(char*)sfreserve(sfstderr,r,SF_LOCKR)))
{
memcpy(sh.prompt,prompt,r);
sfwrite(sfstderr,sh.prompt,r-1);
}
sh.timeout = 0;
save_prompt = sh.nextprompt;
sh.nextprompt = 0;
r=sh_readline(argv,fd,flags,len,timeout);
sh.nextprompt = save_prompt;
if(r==0 && (r=(sfeof(sh.sftable[fd])||sferror(sh.sftable[fd]))))
{
if(fd == sh.cpipe[0] && errno!=EINTR)
sh_pclose(sh.cpipe);
}
return(r);
}
/*
* here for read timeout
*/
static void timedout(void *handle)
{
sfclrlock((Sfio_t*)handle);
sh_exit(1);
}
/*
* This is the code to read a line and to split it into tokens
* <names> is an array of variable names
* <fd> is the file descriptor
* <flags> is union of -A, -r, -s, and contains delimiter if not '\n'
* <timeout> is the number of milliseconds until timeout
*/
int sh_readline(char **names, volatile int fd, int flags, ssize_t size, long timeout)
{
register ssize_t c;
register unsigned char *cp;
register Namval_t *np;
register char *name, *val;
register Sfio_t *iop;
Namfun_t *nfp;
char *ifs;
unsigned char *cpmax;
unsigned char *del;
char was_escape = 0;
char use_stak = 0;
volatile char was_write = 0;
volatile char was_share = 1;
volatile int keytrap;
int rel, wrd;
long array_index = 0;
void *timeslot=0;
int delim = '\n';
int jmpval=0;
int binary;
int oflags=NV_ASSIGN|NV_VARNAME;
char inquote = 0;
struct checkpt buff;
Edit_t *ep = (struct edit*)sh.ed_context;
if(!(iop=sh.sftable[fd]) && !(iop=sh_iostream(fd)))
return(1);
sh_stats(STAT_READS);
if(names && (name = *names))
{
Namval_t *mp;
if(val= strchr(name,'?'))
*val = 0;
if(flags&C_FLAG)
oflags |= NV_ARRAY;
np = nv_open(name,sh.var_tree,oflags);
if(np && nv_isarray(np) && (mp=nv_opensub(np)))
np = mp;
if((flags&V_FLAG) && sh.ed_context)
((struct edit*)sh.ed_context)->e_default = np;
if(flags&A_FLAG)
{
Namarr_t *ap;
flags &= ~A_FLAG;
array_index = 1;
if((ap=nv_arrayptr(np)) && !ap->fun)
ap->nelem++;
nv_unset(np);
if((ap=nv_arrayptr(np)) && !ap->fun)
ap->nelem--;
nv_putsub(np,NIL(char*),0L);
}
else if(flags&C_FLAG)
{
char *sp = np->nvenv;
delim = -1;
nv_unset(np);
if(!nv_isattr(np,NV_MINIMAL))
np->nvenv = sp;
nv_setvtree(np);
}
else
name = *++names;
if(val)
*val = '?';
}
else
{
name = 0;
if(dtvnext(sh.var_tree) || sh.namespace)
np = nv_open(nv_name(REPLYNOD),sh.var_tree,0);
else
np = REPLYNOD;
}
keytrap = ep?ep->e_keytrap:0;
if(size || (flags>>D_FLAG)) /* delimiter not new-line or fixed size read */
{
if((sh.fdstatus[fd]&IOTTY) && !keytrap)
tty_raw(fd,1);
if(!(flags&(N_FLAG|NN_FLAG)))
{
delim = ((unsigned)flags)>>(D_FLAG+1);
ep->e_nttyparm.c_cc[VEOL] = delim;
ep->e_nttyparm.c_lflag |= ISIG;
tty_set(fd,TCSADRAIN,&ep->e_nttyparm);
}
}
binary = nv_isattr(np,NV_BINARY);
if(!binary && !(flags&(N_FLAG|NN_FLAG)))
{
Namval_t *mp;
/* set up state table based on IFS */
ifs = nv_getval(mp=sh_scoped(IFSNOD));
if((flags&R_FLAG) && sh.ifstable['\\']==S_ESC)
sh.ifstable['\\'] = 0;
else if(!(flags&R_FLAG) && sh.ifstable['\\']==0)
sh.ifstable['\\'] = S_ESC;
if(delim>0)
sh.ifstable[delim] = S_NL;
if(delim!='\n')
{
sh.ifstable['\n'] = 0;
nv_putval(mp, ifs, NV_RDONLY);
}
sh.ifstable[0] = S_EOF;
if((flags&SS_FLAG))
{
sh.ifstable['"'] = S_QUOTE;
sh.ifstable['\r'] = S_ERR;
}
}
sfclrerr(iop);
for(nfp=np->nvfun; nfp; nfp = nfp->next)
{
if(nfp->disc && nfp->disc->readf)
{
Namval_t *mp = nv_open(name,sh.var_tree,oflags|NV_NOREF);
if((c=(*nfp->disc->readf)(mp,iop,delim,nfp))>=0)
return(c);
}
}
if(binary && !(flags&(N_FLAG|NN_FLAG)))
{
flags |= NN_FLAG;
size = nv_size(np);
}
was_write = (sfset(iop,SF_WRITE,0)&SF_WRITE)!=0;
if(fd==0)
was_share = (sfset(iop,SF_SHARE,sh.redir0!=2)&SF_SHARE)!=0;
if(timeout || (sh.fdstatus[fd]&(IOTTY|IONOSEEK)))
{
sh_pushcontext(&buff,1);
jmpval = sigsetjmp(buff.buff,0);
if(jmpval)
goto done;
if(timeout)
timeslot = (void*)sh_timeradd(timeout,0,timedout,(void*)iop);
}
if(flags&(N_FLAG|NN_FLAG))
{
char buf[256],*var=buf,*cur,*end,*up,*v;
/* reserved buffer */
if((c=size)>=sizeof(buf))
{
var = (char*)sh_malloc(c+1);
end = var + c;
}
else
end = var + sizeof(buf) - 1;
up = cur = var;
if((sfset(iop,SF_SHARE,1)&SF_SHARE) && fd!=0)
was_share = 1;
if(size==0)
{
cp = sfreserve(iop,0,0);
c = 0;
}
else
{
ssize_t m;
int f;
for (;;)
{
c = size;
if(keytrap)
{
cp = 0;
f = 0;
m = 0;
while(c-->0 && (buf[m]=ed_getchar(ep,0)))
m++;
if(m>0)
cp = (unsigned char*)buf;
}
else
{
f = 1;
if(cp = sfreserve(iop,c,SF_LOCKR))
m = sfvalue(iop);
else if(flags&NN_FLAG)
{
c = size;
m = (cp = sfreserve(iop,c,0)) ? sfvalue(iop) : 0;
f = 0;
}
else
{
c = sfvalue(iop);
m = (cp = sfreserve(iop,c,SF_LOCKR)) ? sfvalue(iop) : 0;
}
}
if(m>0 && (flags&N_FLAG) && !binary && (v=memchr(cp,'\n',m)))
{
*v++ = 0;
m = v-(char*)cp;
}
if((c=m)>size)
c = size;
if(c>0)
{
if(c > (end-cur))
{
ssize_t cx = cur - var, ux = up - var;
m = (end - var) + (c - (end - cur));
if (var == buf)
{
v = (char*)sh_malloc(m+1);
var = memcpy(v, var, cur - var);
}
else
var = sh_newof(var, char, m, 1);
end = var + m;
cur = var + cx;
up = var + ux;
}
if(cur!=(char*)cp)
memcpy((void*)cur,cp,c);
if(f)
sfread(iop,cp,c);
cur += c;
if(mbwide() && !binary)
{
int x;
int z;
mbinit();
*cur = 0;
x = z = 0;
while (up < cur && (z = mbsize(up)) > 0)
{
up += z;
x++;
}
if((size -= x) > 0 && (up >= cur || z < 0) && ((flags & NN_FLAG) || z < 0 || m > c))
continue;
}
}
if(mbwide() && !binary && (up == var || (flags & NN_FLAG) && size))
cur = var;
*cur = 0;
if(c>=size || (flags&N_FLAG) || m==0)
{
if(m)
sfclrerr(iop);
break;
}
size -= c;
}
}
if(timeslot)
sh_timerdel(timeslot);
if(binary && !((size=nv_size(np)) && nv_isarray(np) && c!=size))
{
if((c==size) && np->nvalue.cp && !nv_isarray(np))
memcpy((char*)np->nvalue.cp,var,c);
else
{
Namval_t *mp;
if(var==buf)
var = sh_memdup(var,c+1);
nv_putval(np,var,NV_RAW);
nv_setsize(np,c);
if(!nv_isattr(np,NV_IMPORT|NV_EXPORT) && (mp=(Namval_t*)np->nvenv))
nv_setsize(mp,c);
}
}
else
{
nv_putval(np,var,0);
if(var!=buf)
free((void*)var);
}
goto done;
}
else if(cp = (unsigned char*)sfgetr(iop,delim,0))
c = sfvalue(iop);
else if(cp = (unsigned char*)sfgetr(iop,delim,-1))
{
c = sfvalue(iop)+1;
if(!sferror(iop) && sfgetc(iop) >=0)
{
errormsg(SH_DICT,ERROR_exit(1),e_overlimit,"line length");
UNREACHABLE();
}
}
if(timeslot)
sh_timerdel(timeslot);
if((flags&S_FLAG) && !sh.hist_ptr)
{
sh_histinit();
if(!sh.hist_ptr)
flags &= ~S_FLAG;
}
if(cp)
{
cpmax = cp + c;
#if SHOPT_CRNL
if(delim=='\n' && c>=2 && cpmax[-2]=='\r')
cpmax--;
#endif /* SHOPT_CRNL */
if(*(cpmax-1) != delim)
*(cpmax-1) = delim;
if(flags&S_FLAG)
sfwrite(sh.hist_ptr->histfp,(char*)cp,c);
c = sh.ifstable[*cp++];
#if !SHOPT_MULTIBYTE
if(!name && (flags&R_FLAG)) /* special case single argument */
{
/* skip over leading blanks */
while(c==S_SPACE)
c = sh.ifstable[*cp++];
/* strip trailing delimiters */
if(cpmax[-1] == '\n')
cpmax--;
if(cpmax>cp)
{
while((c=sh.ifstable[*--cpmax])==S_DELIM || c==S_SPACE);
cpmax[1] = 0;
}
else
*cpmax =0;
if(nv_isattr(np, NV_RDONLY))
{
errormsg(SH_DICT,ERROR_warn(0),e_readonly, nv_name(np));
jmpval = 1;
}
else
nv_putval(np,(char*)cp-1,0);
goto done;
}
#endif /* !SHOPT_MULTIBYTE */
}
else
c = S_NL;
sh.nextprompt = 2;
rel= staktell();
mbinit();
/* val==0 at the start of a field */
val = 0;
del = 0;
while(1)
{
ssize_t mbsz;
switch(c)
{
#if SHOPT_MULTIBYTE
case S_MBYTE:
if(val==0)
val = (char*)(cp-1);
if(sh_strchr(ifs,(char*)cp-1)>=0)
{
c = mbsize((char*)cp-1);
if(name)
cp[-1] = 0;
if(c>1)
cp += (c-1);
c = S_DELIM;
}
else
c = 0;
continue;
#endif /* SHOPT_MULTIBYTE */
case S_QUOTE:
c = sh.ifstable[*cp++];
if(inquote && c==S_QUOTE)
c = -1;
else
inquote = !inquote;
if(val)
{
stakputs(val);
use_stak = 1;
*val = 0;
}
if(c==-1)
{
stakputc('"');
c = sh.ifstable[*cp++];
}
continue;
case S_ESC:
/* process escape character */
if((c = sh.ifstable[*cp++]) == S_NL)
was_escape = 1;
else
c = 0;
if(val)
{
stakputs(val);
use_stak = 1;
was_escape = 1;
*val = 0;
}
continue;
case S_ERR:
cp++;
/* FALLTHROUGH */
case S_EOF:
/* check for end of buffer */
if(val && *val)
{
stakputs(val);
use_stak = 1;
}
val = 0;
if(cp>=cpmax)
{
c = S_NL;
break;
}
/* eliminate null bytes */
c = sh.ifstable[*cp++];
if(!name && val && (c==S_SPACE||c==S_DELIM||c==S_MBYTE))
c = 0;
continue;
case S_NL:
if(was_escape)
{
was_escape = 0;
if(cp = (unsigned char*)sfgetr(iop,delim,0))
c = sfvalue(iop);
else if(cp=(unsigned char*)sfgetr(iop,delim,-1))
c = sfvalue(iop)+1;
if(cp)
{
if(flags&S_FLAG)
sfwrite(sh.hist_ptr->histfp,(char*)cp,c);
cpmax = cp + c;
c = sh.ifstable[*cp++];
val=0;
if(!name && (c==S_SPACE || c==S_DELIM || c==S_MBYTE))
c = 0;
continue;
}
}
c = S_NL;
break;
case S_SPACE:
/* skip over blanks */
while((c=sh.ifstable[*cp++])==S_SPACE);
if(!val)
continue;
#if SHOPT_MULTIBYTE
if(c==S_MBYTE)
{
if(sh_strchr(ifs,(char*)cp-1)>=0)
{
if((c = mbsize((char*)cp-1))>1)
cp += (c-1);
c = S_DELIM;
}
else
c = 0;
}
#endif /* SHOPT_MULTIBYTE */
if(c!=S_DELIM)
break;
/* FALLTHROUGH */
case S_DELIM:
if(!del)
del = cp - 1;
if(name)
{
/* skip over trailing blanks */
while((c=sh.ifstable[*cp++])==S_SPACE);
break;
}
/* FALLTHROUGH */
case 0:
if(val==0 || was_escape)
{
val = (char*)(cp-1);
was_escape = 0;
}
/* skip over word characters */
wrd = -1;
/* skip a preceding multibyte character, if any */
if(c == 0 && (mbsz = mbsize(cp-1)) > 1)
cp += mbsz - 1;
while(1)
{
while((c = sh.ifstable[*cp]) == 0)
{
cp += (mbsz = mbsize(cp)) > 1 ? mbsz : 1; /* treat invalid char as 1 byte */
if(!wrd)
wrd = 1;
}
cp++;
if(inquote)
{
if(c==S_QUOTE)
{
if(sh.ifstable[*cp]==S_QUOTE)
{
if(val)
{
stakwrite(val,cp-(unsigned char*)val);
use_stak = 1;
}
val = (char*)++cp;
}
else
break;
}
if(c && c!=S_EOF)
{
if(c==S_NL)
{
if(val)
{
stakwrite(val,cp-(unsigned char*)val);
use_stak=1;
}
if(cp = (unsigned char*)sfgetr(iop,delim,0))
c = sfvalue(iop);
else if(cp = (unsigned char*)sfgetr(iop,delim,-1))
c = sfvalue(iop)+1;
val = (char*)cp;
}
continue;
}
}
if(!del&&c==S_DELIM)
del = cp - 1;
if(name || c==S_NL || c==S_ESC || c==S_EOF || c==S_MBYTE)
break;
if(wrd<0)
wrd = 0;
}
if(wrd>0)
del = (unsigned char*)"";
if(c!=S_MBYTE)
cp[-1] = 0;
continue;
}
/* assign value and advance to next variable */
if(!val)
val = "";
if(use_stak)
{
stakputs(val);
stakputc(0);
val = stakptr(rel);
}
if(!name && *val)
{
/* strip off trailing space delimiters */
register unsigned char *vp = (unsigned char*)val + strlen(val);
while(sh.ifstable[*--vp]==S_SPACE);
if(vp==del)
{
if(vp==(unsigned char*)val)
vp--;
else
while(sh.ifstable[*--vp]==S_SPACE);
}
vp[1] = 0;
}
if(nv_isattr(np, NV_RDONLY))
{
errormsg(SH_DICT,ERROR_warn(0),e_readonly, nv_name(np));
jmpval = 1;
}
else
nv_putval(np,val,0);
val = 0;
del = 0;
if(use_stak)
{
stakseek(rel);
use_stak = 0;
}
if(array_index)
{
nv_putsub(np, NIL(char*), array_index++);
if(c!=S_NL)
continue;
name = *++names;
}
while(1)
{
if(name)
{
np = nv_open(name,sh.var_tree,NV_VARNAME);
name = *++names;
}
else
np = 0;
if(c!=S_NL)
break;
if(!np)
goto done;
if(nv_isattr(np, NV_RDONLY))
{
errormsg(SH_DICT,ERROR_warn(0),e_readonly, nv_name(np));
jmpval = 1;
}
else
nv_putval(np, "", 0);
}
}
done:
if(timeout || (sh.fdstatus[fd]&(IOTTY|IONOSEEK)))
sh_popcontext(&buff);
if(was_write)
sfset(iop,SF_WRITE,1);
if(!was_share)
sfset(iop,SF_SHARE,0);
if((sh.fdstatus[fd]&IOTTY) && !keytrap)
tty_cooked(fd);
if(flags&S_FLAG)
hist_flush(sh.hist_ptr);
if(jmpval > 1)
siglongjmp(*sh.jmplist,jmpval);
return(jmpval);
}

Some files were not shown because too many files have changed in this diff Show More