Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

perl 2.0 (no announcement message available)

Some of the enhancements from Perl1 included:

    * New regexp routines derived from Henry Spencer's.
          o Support for /(foo|bar)/.
          o Support for /(foo)*/ and /(foo)+/.
          o \s for whitespace, \S for non-, \d for digit, \D nondigit 
    * Local variables in blocks, subroutines and evals.
    * Recursive subroutine calls are now supported.
    * Array values may now be interpolated into lists: unlink 'foo', 'bar', @trashcan, 'tmp';
    * File globbing.
    * Use of <> in array contexts returns the whole file or glob list.
    * New iterator for normal arrays, foreach, that allows both read and write.
    * Ability to open pipe to a forked off script for secure pipes in setuid scripts.
    * File inclusion via do 'foo.pl';
    * More file tests, including -t to see if, for instance, stdin is a terminal. File tests now behave in a more correct manner. You can do file tests on filehandles as well as filenames. The special filetests -T and -B test a file to see if it's text or binary.
    * An eof can now be used on each file of the <> input for such purposes as resetting the line numbers or appending to each file of an inplace edit.
    * Assignments can now function as lvalues, so you can say things like ($HOST = $host) =~ tr/a-z/A-Z/; ($obj = $src) =~ s/\.c$/.o/;
    * You can now do certain file operations with a variable which holds the name of a filehandle, e.g. open(++$incl,$includefilename); $foo = <$incl>;
    * Warnings are now available (with -w) on use of uninitialized variables and on identifiers that are mentioned only once, and on reference to various undefined things.
    * There is now a wait operator.
    * There is now a sort operator.
    * The manual is now not lying when it says that perl is generally faster than sed. I hope.
  • Loading branch information...
commit 378cc40b38293ffc7298c6a7ed3cd740ad79be52 1 parent a4de7c0
@TimToady TimToady authored
Showing with 12,147 additions and 4,589 deletions.
  1. +89 −0 Changes
  2. +353 −94 Configure
  3. +3 −3 EXTERN.h
  4. +3 −3 INTERN.h
  5. +151 −108 MANIFEST
  6. +32 −43 Makefile.SH
  7. +5 −3 README
  8. +0 −1  Wishlist
  9. +918 −1,252 arg.c
  10. +94 −21 arg.h
  11. +47 −16 array.c
  12. +10 −6 array.h
  13. +239 −76 cmd.c
  14. +21 −17 cmd.h
  15. +93 −4 config.h.SH
  16. +60 −29 dump.c
  17. +8 −0 eg/ADB
  18. +18 −0 eg/README
  19. +34 −0 eg/changes
  20. +22 −0 eg/dus
  21. +53 −0 eg/findcp
  22. +17 −0 eg/findtar
  23. +114 −0 eg/g/gcp
  24. +77 −0 eg/g/gcp.man
  25. +21 −0 eg/g/ged
  26. +33 −0 eg/g/ghosts
  27. +116 −0 eg/g/gsh
  28. +80 −0 eg/g/gsh.man
  29. +29 −0 eg/myrup
  30. +10 −0 eg/nih
  31. +7 −0 eg/rmfrom
  32. +51 −0 eg/scan/scan_df
  33. +57 −0 eg/scan/scan_last
  34. +222 −0 eg/scan/scan_messages
  35. +30 −0 eg/scan/scan_passwd
  36. +32 −0 eg/scan/scan_ps
  37. +54 −0 eg/scan/scan_sudo
  38. +84 −0 eg/scan/scan_suid
  39. +87 −0 eg/scan/scanner
  40. +24 −0 eg/shmkill
  41. +45 −0 eg/van/empty
  42. +66 −0 eg/van/unvanish
  43. +21 −0 eg/van/vanexp
  44. +65 −0 eg/van/vanish
  45. +1,435 −0 eval.c
  46. +9 −11 form.c
  47. +3 −3 form.h
  48. +19 −4 handy.h
  49. +62 −20 hash.c
  50. +8 −4 hash.h
  51. +38 −0 lib/getopt.pl
  52. +14 −0 lib/importenv.pl
  53. +27 −0 lib/stat.pl
  54. +21 −10 makedepend.SH
  55. +5 −10 makedir.SH
  56. +13 −16 malloc.c
  57. +1 −1  patchlevel.h
  58. +103 −32 perl.h
  59. +463 −75 perl.man.1
  60. +443 −99 perl.man.2
  61. +214 −91 perl.y
  62. +10 −8 perldb
  63. +7 −10 perldb.man
  64. +15 −0 perlsh
  65. +513 −1,269 perly.c
  66. +2,121 −0 regexp.c
  67. +39 −0 regexp.h
  68. +0 −754 search.c
  69. +0 −39 search.h
  70. +12 −11 spat.h
  71. +190 −49 stab.c
  72. +14 −6 stab.h
  73. +62 −34 str.c
  74. +7 −4 str.h
  75. +13 −7 t/TEST
  76. +1 −1  t/base.cond
  77. +1 −1  t/base.if
  78. +7 −2 t/base.lex
  79. +1 −1  t/base.pat
  80. +2 −2 t/base.term
  81. +1 −1  t/cmd.elsif
  82. +26 −2 t/cmd.for
  83. +1 −1  t/cmd.mod
  84. +30 −2 t/cmd.subval
  85. +1 −1  t/cmd.while
  86. +1 −1  t/comp.cmdopt
  87. +1 −1  t/comp.cpp
  88. +1 −1  t/comp.decl
  89. +1 −1  t/comp.multiline
  90. +1 −1  t/comp.script
  91. +3 −2 t/comp.term
  92. +2 −2 t/io.argv
  93. +32 −0 t/io.dup
  94. +25 −6 t/io.fs
  95. +1 −1  t/io.inplace
  96. +21 −0 t/io.pipe
  97. +11 −4 t/io.print
  98. +7 −5 t/io.tell
  99. +1 −1  t/op.append
  100. +9 −2 t/op.auto
  101. +1 −1  t/op.chop
  102. +1 −1  t/op.cond
  103. +0 −12 t/op.crypt
  104. +29 −0 t/op.delete
  105. +12 −2 t/op.do
  106. +5 −2 t/op.each
  107. +25 −3 t/op.eval
  108. +15 −6 t/op.exec
  109. +1 −1  t/op.exp
  110. +2 −2 t/op.flip
  111. +1 −1  t/op.fork
  112. +1 −1  t/op.goto
  113. +1 −1  t/op.int
  114. +1 −1  t/op.join
  115. +27 −2 t/op.list
  116. +15 −16 t/op.magic
  117. +1 −1  t/op.oct
  118. +1 −1  t/op.ord
  119. +41 −2 t/op.pat
  120. +1 −1  t/op.push
  121. +31 −0 t/op.regexp
  122. +1 −1  t/op.repeat
  123. +1 −1  t/op.sleep
  124. +8 −4 t/op.split
  125. +1 −1  t/op.sprintf
  126. +113 −2 t/op.stat
  127. +69 −0 t/op.study
  128. +18 −5 t/op.subst
  129. +1 −1  t/op.time
  130. +1 −1  t/op.unshift
  131. +122 −0 t/re_tests
  132. +1,331 −0 toke.c
  133. +335 −27 util.c
  134. +11 −21 util.h
  135. +3 −3 version.c
  136. +3 −3 x2p/EXTERN.h
  137. +3 −3 x2p/INTERN.h
  138. +11 −15 x2p/Makefile.SH
  139. +3 −14 x2p/a2p.h
  140. +7 −7 x2p/a2p.man
  141. +47 −36 x2p/a2p.y
  142. +63 −18 x2p/a2py.c
  143. +3 −3 x2p/handy.h
  144. +3 −3 x2p/hash.c
  145. +3 −3 x2p/hash.h
  146. +24 −15 x2p/s2p
  147. +7 −7 x2p/s2p.man
  148. +12 −7 x2p/str.c
  149. +3 −3 x2p/str.h
  150. +11 −6 x2p/util.c
  151. +3 −3 x2p/util.h
  152. +50 −34 x2p/walk.c
View
89 Changes
@@ -0,0 +1,89 @@
+New regexp routines derived from Henry Spencer's.
+ Support for /(foo|bar)/.
+ Support for /(foo)*/ and /(foo)+/.
+ \s for whitespace, \S nonwhitespace
+ \d for digit, \D nondigit
+
+Local variables in blocks, subroutines and evals.
+
+Recursive subroutine calls are now supported.
+
+Array values may now be interpolated into lists:
+ unlink 'foo', 'bar', @trashcan, 'tmp';
+
+File globbing via <*.foo>.
+
+Use of <> in array contexts returns the whole file or glob list:
+ unlink <*.foo>;
+
+New iterator for normal arrays, foreach, that allows both read and write:
+ foreach $elem ($array) {
+ $elem =~ s/foo/bar/;
+ }
+
+Ability to open pipe to a forked off script for secure pipes in setuid scripts.
+
+File inclusion via
+ do 'foo.pl';
+
+More file tests, including -t to see if, for instance, stdin is
+a terminal. File tests now behave in a more correct manner. You can do
+file tests on filehandles as well as filenames. The special filetests
+-T and -B test a file to see if it's text or binary.
+
+An eof can now be used on each file of the <> input for such purposes
+as resetting the line numbers or appending to each file of an inplace edit.
+
+Assignments can now function as lvalues, so you can say things like
+ ($HOST = $host) =~ tr/a-z/A-Z/;
+ ($obj = $src) =~ s/\.c$/.o/;
+
+You can now do certain file operations with a variable which holds the name
+of a filehandle, e.g. open(++$incl,$includefilename); $foo = <$incl>;
+
+You can now a subroutine indirectly through a scalar variable:
+ $which = 'xyz';
+ do $which('foo'); # calls xyz
+
+Warnings are now available (with -w) on use of uninitialized variables and on
+identifiers that are mentioned only once, and on reference to various
+undefined things.
+
+The -S switch causes perl to search the PATH for the script so that you can say
+ eval "exec /usr/bin/perl -S $0 $*"
+ if $running_under_some_shell;
+
+Reset now resets arrays and associative arrays as well as string variables.
+
+Assigning off the end of an array now nulls out any intervening values.
+
+$#foo is now an lvalue. You can preallocate or truncate arrays, or recover
+values lost to prior truncation.
+
+$#foo is now indexed to $[ properly.
+
+s/foo/bar/i optimization bug fixed.
+
+The $x = "...$x..."; bug is fixed.
+
+The @ary = (1); bug is now fixed. You can even say @ary = 1;
+
+$= now returns the correct value.
+
+Several of the larger files are now split into smaller pieces for easier
+compilation.
+
+Pattern matches evaluated in an array context now return ($1, $2...).
+
+There is now a wait operator.
+
+There is now a sort operator.
+
+The requirement of parens around certain expressions when taking their value
+has been lifted. In particular, you can say
+ $x = print "foo","bar";
+ $x = unlink "foo","bar";
+ chdir "foo" || die "Can't chdir to foo\n";
+
+The manual is now not lying when it says that perl is generally faster than
+sed. I hope.
View
447 Configure
@@ -8,14 +8,14 @@
# and edit it to reflect your system. Some packages may include samples
# of config.h for certain machines, so you might look for one of those.)
#
-# $Header: Configure,v 1.0.1.6 88/02/02 11:20:07 root Exp $
+# $Header: Configure,v 2.0 88/06/05 00:07:37 root Exp $
#
# Yes, you may rip this off to use in other distribution packages.
# (Note: this Configure script was generated automatically. Rather than
# working with this copy of Configure, you may wish to get metaconfig.)
: sanity checks
-PATH='.:/bin:/usr/bin:/usr/local/bin:/usr/ucb:/usr/local:/usr/lbin:/etc'
+PATH='.:/bin:/usr/bin:/usr/local/bin:/usr/ucb:/usr/local:/usr/lbin:/etc:/usr/new:/usr/new/bin:/usr/nbin'
export PATH || (echo "OOPS, this isn't sh. Desperation time. I will feed myself to sh."; sh $0; kill $$)
if test ! -t 0; then
@@ -34,6 +34,10 @@ if test ! -d ../UU; then
cd UU
fi
+case "$1" in
+-d) shift; fastread='yes';;
+esac
+
d_eunice=''
eunicefix=''
define=''
@@ -61,24 +65,37 @@ Mcc=''
vi=''
mailx=''
mail=''
+cpp=''
Log=''
Header=''
bin=''
cc=''
contains=''
-cpp=''
+cppstdin=''
cppminus=''
d_bcopy=''
d_charsprf=''
d_crypt=''
+d_fchmod=''
+d_fchown=''
+d_getgrps=''
d_index=''
+d_killpg=''
+d_memcpy=''
+d_rename=''
+d_setegid=''
+d_seteuid=''
+d_setrgid=''
+d_setruid=''
d_statblks=''
d_stdstdio=''
+d_strcspn=''
d_strctcpy=''
d_symlink=''
d_tminsys=''
d_vfork=''
d_voidsig=''
+gidtype=''
libc=''
libnm=''
mallocsrc=''
@@ -102,8 +119,10 @@ shsharp=''
sharpbang=''
startsh=''
stdchar=''
+uidtype=''
voidflags=''
defvoidused=''
+privlib=''
CONFIG=''
: set package name
@@ -120,10 +139,23 @@ libpth='/usr/lib /usr/local/lib /lib'
smallmach='pdp11 i8086 z8000 i80286 iAPX286'
rmlist='kit[1-9]isdone kit[1-9][0-9]isdone'
trap 'echo " "; rm -f $rmlist; exit 1' 1 2 3
+
+: We must find out about Eunice early
+eunicefix=':'
+if test -f /etc/unixtovms; then
+ eunicefix=/etc/unixtovms
+fi
+if test -f /etc/unixtovms.exe; then
+ eunicefix=/etc/unixtovms.exe
+fi
+
attrlist="mc68000 sun gcos unix ibm gimpel interdata tss os mert pyr"
attrlist="$attrlist vax pdp11 i8086 z8000 u3b2 u3b5 u3b20 u3b200"
attrlist="$attrlist ns32000 ns16000 iAPX286 mc300 mc500 mc700 sparc"
-pth="/usr/ucb /bin /usr/bin /usr/local /usr/local/bin /usr/lbin /etc /usr/lib"
+attrlist="$attrlist nsc32000 sinix xenix venix posix ansi M_XENIX"
+attrlist="$attrlist $mc68k __STDC__"
+pth="/usr/ucb /bin /usr/bin /usr/local /usr/local/bin /usr/lbin /etc /usr/lib /lib"
+d_newshome="../../NeWS"
defvoidused=7
: some greps do not return status, grrr.
@@ -144,7 +176,7 @@ contains*)
cat >contains <<'EOSS'
grep "$1" "$2" >.greptmp && cat .greptmp && test -s .greptmp
EOSS
-chmod 755 contains
+chmod +x contains
esac
: first determine how to suppress newline on echo command
@@ -167,7 +199,10 @@ rm -f .echotmp
: now set up to do reads with possible shell escape and default assignment
cat <<EOSC >myread
-ans='!'
+case "\$fastread" in
+yes) ans=''; echo " " ;;
+*) ans='!';;
+esac
while expr "X\$ans" : "X!" >/dev/null; do
read ans
case "\$ans" in
@@ -273,6 +308,10 @@ for dir in \$*; do
if test -f \$dir/\$thing; then
echo \$dir/\$thing
exit 0
+ elif test -f \$dir/\$thing.exe; then
+ : on Eunice apparently
+ echo \$dir/\$thing
+ exit 0
fi
;;
esac
@@ -280,7 +319,7 @@ done
echo \$dflt
exit 1
EOSC
-chmod 755 loc
+chmod +x loc
$eunicefix loc
loclist="
expr
@@ -300,6 +339,7 @@ trylist="
test
egrep
Mcc
+cpp
"
for file in $loclist; do
xxx=`loc $file $file $pth`
@@ -398,6 +438,12 @@ if test -f /lib/libc.a; then
libc=/lib/libc.a
else
ans=`loc libc.a blurfl/dyick $libpth`
+ if test ! -f $ans; then
+ ans=`loc clib blurfl/dyick $libpth`
+ fi
+ if test ! -f $ans; then
+ ans=`loc libc blurfl/dyick $libpth`
+ fi
if test -f $ans; then
echo "Your C library is in $ans, of all places."
libc=$ans
@@ -423,17 +469,23 @@ EOM
fi
echo " "
$echo $n "Extracting names from $libc for later perusal...$c"
-if ar t $libc > libc.list; then
+nm $libc 2>/dev/null | sed -n -e 's/^.* T _//p' -e 's/^.* T //p' > libc.list
+if $contains '^printf$' libc.list >/dev/null 2>&1; then
echo "done"
else
- echo " "
- echo "The archiver doesn't think $libc is a reasonable library."
- echo "Trying nm instead..."
- if nm -g $libc > libc.list; then
- echo "Done. Maybe this is Unicos, or an Apollo?"
+ nm $libc 2>/dev/null | sed -n -e 's/^.* D _//p' -e 's/^.* D //p' > libc.list
+ if $contains '^printf$' libc.list >/dev/null 2>&1; then
+ echo "done"
else
- echo "That didn't work either. Giving up."
- exit 1
+ echo " "
+ echo "nm didn't seem to work right."
+ echo "Trying ar instead..."
+ if ar t $libc | sed -e 's/\.o$//' > libc.list; then
+ echo "Ok."
+ else
+ echo "That didn't work either. Giving up."
+ exit 1
+ fi
fi
fi
rmlist="$rmlist libc.list"
@@ -446,7 +498,7 @@ if $contains SIGTSTP /usr/include/signal.h >/dev/null 2>&1 ; then
echo exit 0 >bsd
echo exit 1 >usg
echo exit 1 >v7
-elif $contains fcntl libc.list >/dev/null 2>&1 ; then
+elif $contains '^fcntl$' libc.list >/dev/null 2>&1 ; then
echo "Looks kind of like a USG system, but we'll see..."
echo exit 1 >bsd
echo exit 0 >usg
@@ -457,7 +509,7 @@ else
echo exit 1 >usg
echo exit 0 >v7
fi
-if $contains vmssystem libc.list >/dev/null 2>&1 ; then
+if $contains '^vmssystem$' libc.list >/dev/null 2>&1 ; then
cat <<'EOI'
There is, however, a strange, musty smell in the air that reminds me of
something...hmm...yes...I've got it...there's a VMS nearby, or I'm a Blit.
@@ -481,7 +533,8 @@ else
echo "It's not Xenix..."
echo "exit 1" >xenix
fi
-chmod 755 xenix
+chmod +x xenix
+$eunicefix xenix
if test -f /venix; then
echo "Actually, this looks more like a VENIX system..."
echo "exit 0" >venix
@@ -494,8 +547,8 @@ else
fi
echo "exit 1" >venix
fi
-chmod 755 bsd usg v7 eunice venix xenix
-$eunicefix bsd usg v7 eunice venix xenix
+chmod +x bsd usg v7 eunice venix
+$eunicefix bsd usg v7 eunice venix
rmlist="$rmlist bsd usg v7 eunice venix xenix"
: see if sh knows # comments
@@ -509,15 +562,15 @@ if sh -c '#' >/dev/null 2>&1 ; then
echo "Okay, let's see if #! works on this system..."
echo "#!/bin/echo hi" > try
$eunicefix try
- chmod 755 try
+ chmod +x try
try > today
- if test -s today; then
+ if $contains hi today >/dev/null 2>&1; then
echo "It does."
sharpbang='#!'
else
echo "#! /bin/echo hi" > try
$eunicefix try
- chmod 755 try
+ chmod +x try
try > today
if test -s today; then
echo "It does."
@@ -531,7 +584,7 @@ else
echo "Your sh doesn't grok # comments--I will strip them later on."
shsharp=false
echo "exec grep -v '^#'" >spitshell
- chmod 755 spitshell
+ chmod +x spitshell
$eunicefix spitshell
spitshell=`pwd`/spitshell
echo "I presume that if # doesn't work, #! won't work either!"
@@ -549,7 +602,7 @@ set abc
test "$?abc" != 1
EOSS
-chmod 755 try
+chmod +x try
$eunicefix try
if try; then
echo "Yup, it does."
@@ -566,61 +619,61 @@ cat <<'EOT' >testcpp.c
#define XYZ xyz
ABC.XYZ
EOT
-echo 'Maybe "/lib/cpp" will work...'
-/lib/cpp <testcpp.c >testcpp.out 2>&1
+echo 'Maybe "'$cpp'" will work...'
+$cpp <testcpp.c >testcpp.out 2>&1
if $contains 'abc.xyz' testcpp.out >/dev/null 2>&1 ; then
echo "Yup, it does."
- cpp='/lib/cpp'
+ cppstdin="$cpp"
cppminus='';
else
- echo 'Nope, maybe "/lib/cpp -" will work...'
- /lib/cpp - <testcpp.c >testcpp.out 2>&1
+ echo 'Nope, maybe "'$cpp' -" will work...'
+ $cpp - <testcpp.c >testcpp.out 2>&1
if $contains 'abc.xyz' testcpp.out >/dev/null 2>&1 ; then
echo "Yup, it does."
- cpp='/lib/cpp'
+ cppstdin="$cpp"
cppminus='-';
else
echo 'No such luck...maybe "cc -E" will work...'
cc -E <testcpp.c >testcpp.out 2>&1
if $contains 'abc.xyz' testcpp.out >/dev/null 2>&1 ; then
echo "It works!"
- cpp='cc -E'
+ cppstdin='cc -E'
cppminus='';
else
echo 'Nixed again...maybe "cc -E -" will work...'
cc -E - <testcpp.c >testcpp.out 2>&1
if $contains 'abc.xyz' testcpp.out >/dev/null 2>&1 ; then
echo "Hooray, it works! I was beginning to wonder."
- cpp='cc -E'
+ cppstdin='cc -E'
cppminus='-';
else
echo 'Nope...maybe "cc -P" will work...'
cc -P <testcpp.c >testcpp.out 2>&1
if $contains 'abc.xyz' testcpp.out >/dev/null 2>&1 ; then
echo "Yup, that does."
- cpp='cc -P'
+ cppstdin='cc -P'
cppminus='';
else
echo 'Nope...maybe "cc -P -" will work...'
cc -P - <testcpp.c >testcpp.out 2>&1
if $contains 'abc.xyz' testcpp.out >/dev/null 2>&1 ; then
echo "Yup, that does."
- cpp='cc -P'
+ cppstdin='cc -P'
cppminus='-';
else
echo 'Hmm...perhaps you already told me...'
- case "$cpp" in
+ case "$cppstdin" in
'') ;;
- *) $cpp $cppminus <testcpp.c >testcpp.out 2>&1;;
+ *) $cppstdin $cppminus <testcpp.c >testcpp.out 2>&1;;
esac
if $contains 'abc.xyz' testcpp.out >/dev/null 2>&1 ; then
echo "Hooray, you did! I was beginning to wonder."
else
echo 'Uh-uh. Time to get fancy...'
echo 'Trying (cat >/tmp/$$.c; cc -E /tmp/$$.c; rm /tmp/$$.c)'
- cpp='(cat >/tmp/$$.c; cc -E /tmp/$$.c; rm /tmp/$$.c)'
+ cppstdin='(cat >/tmp/$$.c; cc -E /tmp/$$.c; rm /tmp/$$.c)'
cppminus='';
- $cpp <testcpp.c >testcpp.out 2>&1
+ $cppstdin <testcpp.c >testcpp.out 2>&1
if $contains 'abc.xyz' testcpp.out >/dev/null 2>&1 ; then
echo "Eureka!."
else
@@ -628,8 +681,8 @@ else
$echo $n "No dice. I can't find a C preprocessor. Name one: $c"
rp='Name a C preprocessor:'
. myread
- cpp="$ans"
- $cpp <testcpp.c >testcpp.out 2>&1
+ cppstdin="$ans"
+ $cppstdin <testcpp.c >testcpp.out 2>&1
if $contains 'abc.xyz' testcpp.out >/dev/null 2>&1 ; then
echo "OK, that will do."
else
@@ -648,7 +701,7 @@ rm -f testcpp.c testcpp.out
: see if bcopy exists
echo " "
-if $contains bcopy libc.list >/dev/null 2>&1; then
+if $contains '^bcopy$' libc.list >/dev/null 2>&1; then
echo 'bcopy() found.'
d_bcopy="$define"
else
@@ -658,17 +711,21 @@ fi
: see if sprintf is declared as int or pointer to char
echo " "
-if $contains 'char.*sprintf' /usr/include/stdio.h >/dev/null 2>&1 ; then
- echo "Your sprintf() returns (char*)."
- d_charsprf="$define"
-else
+cat >.ucbsprf.c <<'EOF'
+main() { char buf[10]; exit((unsigned long)sprintf(buf,"%s","foo") > 10L); }
+EOF
+if cc .ucbsprf.c -o .ucbsprf >/dev/null 2>&1 && .ucbsprf; then
echo "Your sprintf() returns (int)."
d_charsprf="$undef"
+else
+ echo "Your sprintf() returns (char*)."
+ d_charsprf="$define"
fi
+/bin/rm -f .ucbsprf.c .ucbsprf
: see if crypt exists
echo " "
-if $contains crypt libc.list >/dev/null 2>&1; then
+if $contains '^crypt$' libc.list >/dev/null 2>&1; then
echo 'crypt() found.'
d_crypt="$define"
else
@@ -676,27 +733,134 @@ else
d_crypt="$undef"
fi
+: see if fchmod exists
+echo " "
+if $contains '^fchmod$' libc.list >/dev/null 2>&1; then
+ echo 'fchmod() found.'
+ d_fchmod="$define"
+else
+ echo 'fchmod() not found.'
+ d_fchmod="$undef"
+fi
+
+: see if fchown exists
+echo " "
+if $contains '^fchown$' libc.list >/dev/null 2>&1; then
+ echo 'fchown() found.'
+ d_fchown="$define"
+else
+ echo 'fchown() not found.'
+ d_fchown="$undef"
+fi
+
+: see if getgroups exists
+echo " "
+if $contains '^getgroups$' libc.list >/dev/null 2>&1; then
+ echo 'getgroups() found.'
+ d_getgrps="$define"
+else
+ echo 'getgroups() not found.'
+ d_getgrps="$undef"
+fi
+
: index or strcpy
echo " "
-dflt=y
-if $contains index libc.list >/dev/null 2>&1 ; then
- echo "Your system appears to use index() and rindex() rather than strchr()"
- $echo $n "and strrchr(). Is this correct? [$dflt] $c"
- rp='index() rather than strchr()? [$dflt]'
- . myread
- case "$ans" in
- n*|f*) d_index="$define" ;;
- *) d_index="$undef" ;;
- esac
+case "$d_index" in
+n) dflt=n;;
+*) dflt=y;;
+esac
+if $contains '^index$' libc.list >/dev/null 2>&1 ; then
+ if $contains '^strchr$' libc.list >/dev/null 2>&1 ; then
+ echo "Your system has both index() and strchr(). Shall I use"
+ rp="index() rather than strchr()? [$dflt]"
+ $echo $n "$rp $c"
+ . myread
+ case "$ans" in
+ n*) d_index="$define" ;;
+ *) d_index="$undef" ;;
+ esac
+ else
+ d_index="$undef"
+ echo "index() found."
+ fi
else
- echo "Your system appears to use strchr() and strrchr() rather than index()"
- $echo $n "and rindex(). Is this correct? [$dflt] $c"
- rp='strchr() rather than index()? [$dflt]'
- . myread
- case "$ans" in
- n*|f*) d_index="$undef" ;;
- *) d_index="$define" ;;
- esac
+ if $contains '^strchr$' libc.list >/dev/null 2>&1 ; then
+ d_index="$define"
+ echo "strchr() found."
+ else
+ echo "No index() or strchr() found!"
+ d_index="$undef"
+ fi
+fi
+
+: see if killpg exists
+echo " "
+if $contains '^killpg$' libc.list >/dev/null 2>&1; then
+ echo 'killpg() found.'
+ d_killpg="$define"
+else
+ echo 'killpg() not found.'
+ d_killpg="$undef"
+fi
+
+: see if memcpy exists
+echo " "
+if $contains '^memcpy$' libc.list >/dev/null 2>&1; then
+ echo 'memcpy() found.'
+ d_memcpy="$define"
+else
+ echo 'memcpy() not found.'
+ d_memcpy="$undef"
+fi
+
+: see if rename exists
+echo " "
+if $contains '^rename$' libc.list >/dev/null 2>&1; then
+ echo 'rename() found.'
+ d_rename="$define"
+else
+ echo 'rename() not found.'
+ d_rename="$undef"
+fi
+
+: see if setegid exists
+echo " "
+if $contains '^setegid$' libc.list >/dev/null 2>&1; then
+ echo 'setegid() found.'
+ d_setegid="$define"
+else
+ echo 'setegid() not found.'
+ d_setegid="$undef"
+fi
+
+: see if seteuid exists
+echo " "
+if $contains '^seteuid$' libc.list >/dev/null 2>&1; then
+ echo 'seteuid() found.'
+ d_seteuid="$define"
+else
+ echo 'seteuid() not found.'
+ d_seteuid="$undef"
+fi
+
+: see if setrgid exists
+echo " "
+if $contains '^setrgid$' libc.list >/dev/null 2>&1; then
+ echo 'setrgid() found.'
+ d_setrgid="$define"
+else
+ echo 'setrgid() not found.'
+ d_setrgid="$undef"
+fi
+
+: see if setruid exists
+echo " "
+if $contains '^setruid$' libc.list >/dev/null 2>&1; then
+ echo 'setruid() found.'
+ d_setruid="$define"
+else
+ echo 'setruid() not found.'
+ d_setruid="$undef"
fi
: see if stat knows about block sizes
@@ -729,6 +893,16 @@ else
d_stdstdio="$undef"
fi
+: see if strcspn exists
+echo " "
+if $contains '^strcspn$' libc.list >/dev/null 2>&1; then
+ echo 'strcspn() found.'
+ d_strcspn="$define"
+else
+ echo 'strcspn() not found.'
+ d_strcspn="$undef"
+fi
+
: check for structure copying
echo " "
echo "Checking to see if your C compiler can copy structs..."
@@ -751,6 +925,16 @@ else
fi
$rm -f try.*
+: see if symlink exists
+echo " "
+if $contains '^symlink$' libc.list >/dev/null 2>&1; then
+ echo 'symlink() found.'
+ d_symlink="$define"
+else
+ echo 'symlink() not found.'
+ d_symlink="$undef"
+fi
+
: see if struct tm is defined in sys/time.h
echo " "
if $contains 'struct tm' /usr/include/time.h >/dev/null 2>&1 ; then
@@ -763,7 +947,7 @@ fi
: see if there is a vfork
echo " "
-if $contains vfork libc.list >/dev/null 2>&1 ; then
+if $contains '^vfork$' libc.list >/dev/null 2>&1 ; then
echo "vfork() found."
d_vfork="$undef"
else
@@ -801,13 +985,13 @@ void main() {
main() {
#endif
extern void *moo();
- void (*goo)();
+ void *(*goo)();
#if TRY & 2
void (*foo[10])();
#endif
#if TRY & 4
- if(goo == moo) {
+ if(*goo == moo) {
exit(0);
}
#endif
@@ -851,19 +1035,28 @@ $echo $n "$rp $c"
voidflags="$ans"
$rm -f try.* .out
-: see what type of char stdio uses.
+: see what type gids are declared as in the kernel
+case "$gidtype" in
+'')
+ if $contains 'gid_t;' /usr/include/sys/types.h >/dev/null 2>&1 ; then
+ dflt='gid_t';
+ else
+ set `grep 'groups\[NGROUPS\];' /usr/include/sys/user.h 2>/dev/null` unsigned short
+ case $1 in
+ unsigned) dflt="$1 $2" ;;
+ *) dflt="$1" ;;
+ esac
+ fi
+ ;;
+*) dflt="$gidtype"
+ ;;
+esac
+cont=true
echo " "
-if $contains 'unsigned.*char.*_ptr;' /usr/include/stdio.h >/dev/null 2>&1 ; then
- echo "Your stdio uses unsigned chars."
- stdchar="unsigned char"
-else
- echo "Your stdio uses signed chars."
- stdchar="char"
-fi
-
-: preserve RCS keywords in files with variable substitution, grrr
-Log='$Log'
-Header='$Header'
+rp="What type are group ids on this system declared as? [$dflt]"
+$echo $n "$rp $c"
+. myread
+gidtype="$ans"
: set up shell script to do ~ expansion
cat >filexp <<EOSS
@@ -900,9 +1093,65 @@ case "\$1" in
;;
esac
EOSS
-chmod 755 filexp
+chmod +x filexp
$eunicefix filexp
+: determine where private executables go
+case "$privlib" in
+'')
+ dflt=/usr/lib/perl
+ test -d /usr/local/lib && dflt=/usr/local/lib/perl
+ ;;
+*) dflt="$privlib"
+ ;;
+esac
+$cat <<EOM
+
+The perl package has some perl subroutine libraries that should be put in
+a directory that is accessible by everyone. Where do you want to put these
+EOM
+$echo $n "libraries? [$dflt] $c"
+rp="Put perl libraries where? [$dflt]"
+. myread
+privlib=`filexp $ans`
+
+: see what type of char stdio uses.
+echo " "
+if $contains 'unsigned.*char.*_ptr;' /usr/include/stdio.h >/dev/null 2>&1 ; then
+ echo "Your stdio uses unsigned chars."
+ stdchar="unsigned char"
+else
+ echo "Your stdio uses signed chars."
+ stdchar="char"
+fi
+
+: see what type uids are declared as in the kernel
+case "$uidtype" in
+'')
+ if $contains 'uid_t;' /usr/include/sys/types.h >/dev/null 2>&1 ; then
+ dflt='uid_t';
+ else
+ set `grep '_ruid;' /usr/include/sys/user.h 2>/dev/null` unsigned short
+ case $1 in
+ unsigned) dflt="$1 $2" ;;
+ *) dflt="$1" ;;
+ esac
+ fi
+ ;;
+*) dflt="$uidtype"
+ ;;
+esac
+cont=true
+echo " "
+rp="What type are user ids on this system declared as? [$dflt]"
+$echo $n "$rp $c"
+. myread
+uidtype="$ans"
+
+: preserve RCS keywords in files with variable substitution, grrr
+Log='$Log'
+Header='$Header'
+
: determine where public executables go
case "$bin" in
'')
@@ -968,6 +1217,9 @@ case "$mansrc" in
*n)
manext=n
;;
+*C)
+ manext=C
+ ;;
*)
manext=1
;;
@@ -1008,7 +1260,7 @@ exit 0; _ _ _ _\1\\ \1\\
#endif\\
/' >/tmp/Cppsym\$\$
echo exit 1 >>/tmp/Cppsym\$\$
-$cpp $cppminus </tmp/Cppsym\$\$ >/tmp/Cppsym2\$\$
+$cppstdin $cppminus </tmp/Cppsym\$\$ >/tmp/Cppsym2\$\$
case "\$list" in
true) awk 'NF > 5 {print substr(\$6,2,100)}' </tmp/Cppsym2\$\$ ;;
*)
@@ -1019,7 +1271,7 @@ esac
$rm -f /tmp/Cppsym\$\$ /tmp/Cppsym2\$\$
exit \$status
EOSS
-chmod 755 Cppsym
+chmod +x Cppsym
$eunicefix Cppsym
echo "Your C preprocessor defines the following symbols:"
Cppsym -l $attrlist >Cppsym.true
@@ -1245,16 +1497,6 @@ else
cc=cc
fi
-: see if symlink exists
-echo " "
-if $contains symlink libc.list >/dev/null 2>&1; then
- echo 'symlink() found.'
- d_symlink="$define"
-else
- echo 'symlink() not found.'
- d_symlink="$undef"
-fi
-
: see if we should include -lnm
echo " "
if $test -r /usr/lib/libnm.a || $test -r /usr/local/lib/libnm.a ; then
@@ -1341,24 +1583,37 @@ Mcc='$Mcc'
vi='$vi'
mailx='$mailx'
mail='$mail'
+cpp='$cpp'
Log='$Log'
Header='$Header'
bin='$bin'
cc='$cc'
contains='$contains'
-cpp='$cpp'
+cppstdin='$cppstdin'
cppminus='$cppminus'
d_bcopy='$d_bcopy'
d_charsprf='$d_charsprf'
d_crypt='$d_crypt'
+d_fchmod='$d_fchmod'
+d_fchown='$d_fchown'
+d_getgrps='$d_getgrps'
d_index='$d_index'
+d_killpg='$d_killpg'
+d_memcpy='$d_memcpy'
+d_rename='$d_rename'
+d_setegid='$d_setegid'
+d_seteuid='$d_seteuid'
+d_setrgid='$d_setrgid'
+d_setruid='$d_setruid'
d_statblks='$d_statblks'
d_stdstdio='$d_stdstdio'
+d_strcspn='$d_strcspn'
d_strctcpy='$d_strctcpy'
d_symlink='$d_symlink'
d_tminsys='$d_tminsys'
d_vfork='$d_vfork'
d_voidsig='$d_voidsig'
+gidtype='$gidtype'
libc='$libc'
libnm='$libnm'
mallocsrc='$mallocsrc'
@@ -1382,8 +1637,10 @@ shsharp='$shsharp'
sharpbang='$sharpbang'
startsh='$startsh'
stdchar='$stdchar'
+uidtype='$uidtype'
voidflags='$voidflags'
defvoidused='$defvoidused'
+privlib='$privlib'
CONFIG=true
EOT
@@ -1391,6 +1648,7 @@ CONFIG=true
echo " "
dflt=''
+fastread=''
echo "If you didn't make any mistakes, then just type a carriage return here."
rp="If you need to edit config.sh, do it as a shell escape here:"
$echo $n "$rp $c"
@@ -1400,6 +1658,7 @@ case "$ans" in
*) : in case they cannot read
eval $ans;;
esac
+. ./config.sh
echo " "
echo "Doing variable substitutions on .SH files..."
View
6 EXTERN.h
@@ -1,8 +1,8 @@
-/* $Header: EXTERN.h,v 1.0 87/12/18 13:02:26 root Exp $
+/* $Header: EXTERN.h,v 2.0 88/06/05 00:07:46 root Exp $
*
* $Log: EXTERN.h,v $
- * Revision 1.0 87/12/18 13:02:26 root
- * Initial revision
+ * Revision 2.0 88/06/05 00:07:46 root
+ * Baseline version 2.0.
*
*/
View
6 INTERN.h
@@ -1,8 +1,8 @@
-/* $Header: INTERN.h,v 1.0 87/12/18 13:02:39 root Exp $
+/* $Header: INTERN.h,v 2.0 88/06/05 00:07:49 root Exp $
*
* $Log: INTERN.h,v $
- * Revision 1.0 87/12/18 13:02:39 root
- * Initial revision
+ * Revision 2.0 88/06/05 00:07:49 root
+ * Baseline version 2.0.
*
*/
View
259 MANIFEST
@@ -2,111 +2,154 @@ After all the perl kits are run you should have the following files:
Filename Kit Description
-------- --- -----------
-Configure 6 Run this first
-EXTERN.h 10 Included before foreign .h files
-INTERN.h 10 Included before domestic .h files
-MANIFEST 8 This list of files
-Makefile.SH 4 Precursor to Makefile
-README 1 The Instructions
-Wishlist 10 Some things that may or may not happen
-arg.c 3 Expression evaluation
-arg.h 8 Public declarations for the above
-array.c 6 Numerically subscripted arrays
-array.h 10 Public declarations for the above
-cmd.c 7 Command interpreter
-cmd.h 9 Public declarations for the above
-config.H 9 Sample config.h
-config.h.SH 9 Produces config.h.
-dump.c 8 Debugging output
-form.c 8 Format processing
-form.h 10 Public declarations for the above
-handy.h 10 Handy definitions
-hash.c 9 Associative arrays
-hash.h 10 Public declarations for the above
-makedepend.SH 9 Precursor to makedepend
-makedir.SH 10 Precursor to makedir
-malloc.c 7 A version of malloc you might not want
-patchlevel.h 1 The current patch level of perl
-perl.h 9 Global declarations
-perl.man.1 5 The manual page(s), first half
-perl.man.2 4 The manual page(s), second half
-perl.y 5 Yacc grammar for perl
-perly.c 2 The perl compiler
-search.c 6 String matching
-search.h 10 Public declarations for the above
-spat.h 10 Search pattern declarations
-stab.c 8 Symbol table stuff
-stab.h 10 Public declarations for the above
-str.c 4 String handling package
-str.h 10 Public declarations for the above
-t/README 10 Instructions for regression tests
-t/TEST 10 The regression tester
-t/base.cond 10 See if conditionals work
-t/base.if 10 See if if works
-t/base.lex 10 See if lexical items work
-t/base.pat 10 See if pattern matching works
-t/base.term 10 See if various terms work
-t/cmd.elsif 10 See if else-if works
-t/cmd.for 10 See if for loops work
-t/cmd.mod 10 See if statement modifiers work
-t/cmd.subval 10 See if subroutine values work
-t/cmd.while 7 See if while loops work
-t/comp.cmdopt 9 See if command optimization works
-t/comp.cpp 10 See if C preprocessor works
-t/comp.decl 10 See if declarations work
-t/comp.multiline 10 See if multiline strings work
-t/comp.script 10 See if script invokation works
-t/comp.term 10 See if more terms work
-t/io.argv 10 See if ARGV stuff works
-t/io.fs 5 See if directory manipulations work
-t/io.inplace 10 See if inplace editing works
-t/io.print 10 See if print commands work
-t/io.tell 10 See if file seeking works
-t/op.append 10 See if . works
-t/op.auto 9 See if autoincrement et all work
-t/op.chop 10 See if chop works
-t/op.cond 10 See if conditional expressions work
-t/op.crypt 10 See if crypt works
-t/op.do 10 See if subroutines work
-t/op.each 10 See if associative iterators work
-t/op.exec 10 See if exec and system work
-t/op.exp 10 See if math functions work
-t/op.flip 10 See if range operator works
-t/op.fork 10 See if fork works
-t/op.goto 10 See if goto works
-t/op.int 10 See if int works
-t/op.join 10 See if join works
-t/op.list 10 See if array lists work
-t/op.magic 10 See if magic variables work
-t/op.oct 10 See if oct and hex work
-t/op.ord 10 See if ord works
-t/op.pat 9 See if esoteric patterns work
-t/op.push 7 See if push and pop work
-t/op.repeat 10 See if x operator works
-t/op.sleep 6 See if sleep works
-t/op.split 10 See if split works
-t/op.sprintf 10 See if sprintf work
-t/op.stat 10 See if stat work
-t/op.subst 10 See if substitutions work
-t/op.time 10 See if time functions work
-t/op.unshift 10 See if unshift works
-util.c 9 Utility routines
-util.h 10 Public declarations for the above
-version.c 10 Prints version of perl
-x2p/EXTERN.h 10 Same as above
-x2p/INTERN.h 10 Same as above
-x2p/Makefile.SH 9 Precursor to Makefile
-x2p/a2p.h 8 Global declarations
-x2p/a2p.man 8 Manual page for awk to perl translator
-x2p/a2p.y 8 A yacc grammer for awk
-x2p/a2py.c 7 Awk compiler, sort of
-x2p/handy.h 10 Handy definitions
-x2p/hash.c 9 Associative arrays again
-x2p/hash.h 10 Public declarations for the above
-x2p/s2p 1 Sed to perl translator
-x2p/s2p.man 10 Manual page for sed to perl translator
-x2p/str.c 7 String handling package
-x2p/str.h 10 Public declarations for the above
-x2p/util.c 9 Utility routines
-x2p/util.h 10 Public declarations for the above
-x2p/walk.c 1 Parse tree walker
+Changes 13 Differences between 1.0 level 29 and 2.0 level 0
+Configure 6 Run this first
+EXTERN.h 6 Included before foreign .h files
+INTERN.h 15 Included before domestic .h files
+MANIFEST 11 This list of files
+Makefile.SH 13 Precursor to Makefile
+README 1 The Instructions
+Wishlist 4 Some things that may or may not happen
+arg.c 1 Expression evaluation
+arg.h 12 Public declarations for the above
+array.c 13 Numerically subscripted arrays
+array.h 15 Public declarations for the above
+cmd.c 10 Command interpreter
+cmd.h 13 Public declarations for the above
+config.H 13 Sample config.h
+config.h.SH 11 Produces config.h.
+dump.c 12 Debugging output
+eg/ADB 15 An adb wrapper to put in your crash dir
+eg/README 1 Intro to example perl scripts
+eg/changes 15 A program to list recently changed files
+eg/dus 15 A program to do du -s on non-mounted dirs
+eg/findcp 14 A find wrapper that implements a -cp switch
+eg/findtar 15 A find wrapper that pumps out a tar file
+eg/g/gcp 14 A program to do a global rcp
+eg/g/gcp.man 14 Manual page for gcp
+eg/g/ged 1 A program to do a global edit
+eg/g/ghosts 15 A sample /etc/ghosts file
+eg/g/gsh 10 A program to do a global rsh
+eg/g/gsh.man 14 Manual page for gsh
+eg/myrup 15 A program to find lightly loaded machines
+eg/nih 15 Script to insert #! workaround
+eg/rmfrom 15 A program to feed doomed filenames to
+eg/scan/scan_df 14 Scan for filesystem anomalies
+eg/scan/scan_last 14 Scan for login anomalies
+eg/scan/scan_messages 13 Scan for console message anomalies
+eg/scan/scan_passwd 15 Scan for passwd file anomalies
+eg/scan/scan_ps 15 Scan for process anomalies
+eg/scan/scan_sudo 14 Scan for sudo anomalies
+eg/scan/scan_suid 8 Scan for setuid anomalies
+eg/scan/scanner 14 An anomaly reporter
+eg/shmkill 15 A program to remove unused shared memory
+eg/van/empty 15 A program to empty the trashcan
+eg/van/unvanish 14 A program to undo what vanish does
+eg/van/vanexp 15 A program to expire vanished files
+eg/van/vanish 14 A program to put files in a trashcan
+eval.c 8 The expression evaluator
+form.c 12 Format processing
+form.h 15 Public declarations for the above
+handy.h 15 Handy definitions
+hash.c 12 Associative arrays
+hash.h 14 Public declarations for the above
+lib/getopt.pl 14 Perl library supporting option parsing
+lib/importenv.pl 15 Perl routine to get environment into variables.
+lib/stat.pl 15 Perl library supporting stat function
+makedepend.SH 5 Precursor to makedepend
+makedir.SH 14 Precursor to makedir
+malloc.c 11 A version of malloc you might not want
+patchlevel.h 12 The current patch level of perl
+perl.h 12 Global declarations
+perl.man.1 5 The manual page(s), first half
+perl.man.2 3 The manual page(s), second half
+perl.y 10 Yacc grammar for perl
+perldb 11 Perl symbolic debugger
+perldb.man 13 Manual page for perl debugger
+perlsh 15 A poor man's perl shell.
+perly.c 4 The perl compiler
+regexp.c 2 String matching
+regexp.h 14 Public declarations for the above
+spat.h 14 Search pattern declarations
+stab.c 6 Symbol table stuff
+stab.h 3 Public declarations for the above
+str.c 7 String handling package
+str.h 14 Public declarations for the above
+t/README 1 Instructions for regression tests
+t/TEST 14 The regression tester
+t/base.cond 15 See if conditionals work
+t/base.if 15 See if if works
+t/base.lex 15 See if lexical items work
+t/base.pat 15 See if pattern matching works
+t/base.term 15 See if various terms work
+t/cmd.elsif 15 See if else-if works
+t/cmd.for 15 See if for loops work
+t/cmd.mod 15 See if statement modifiers work
+t/cmd.subval 14 See if subroutine values work
+t/cmd.while 14 See if while loops work
+t/comp.cmdopt 13 See if command optimization works
+t/comp.cpp 15 See if C preprocessor works
+t/comp.decl 15 See if declarations work
+t/comp.multiline 15 See if multiline strings work
+t/comp.script 14 See if script invokation works
+t/comp.term 15 See if more terms work
+t/io.argv 15 See if ARGV stuff works
+t/io.dup 15 See if >& works right
+t/io.fs 12 See if directory manipulations work
+t/io.inplace 15 See if inplace editing works
+t/io.pipe 15 See if secure pipes work
+t/io.print 15 See if print commands work
+t/io.tell 13 See if file seeking works
+t/op.append 15 See if . works
+t/op.auto 14 See if autoincrement et all work
+t/op.chop 15 See if chop works
+t/op.cond 5 See if conditional expressions work
+t/op.delete 15 See if delete works
+t/op.do 14 See if subroutines work
+t/op.each 14 See if associative iterators work
+t/op.eval 14 See if eval operator works
+t/op.exec 15 See if exec and system work
+t/op.exp 15 See if math functions work
+t/op.flip 15 See if range operator works
+t/op.fork 15 See if fork works
+t/op.goto 15 See if goto works
+t/op.int 15 See if int works
+t/op.join 15 See if join works
+t/op.list 14 See if array lists work
+t/op.magic 15 See if magic variables work
+t/op.oct 15 See if oct and hex work
+t/op.ord 15 See if ord works
+t/op.pat 14 See if esoteric patterns work
+t/op.push 15 See if push and pop work
+t/op.regexp 15 See if regular expressions work
+t/op.repeat 15 See if x operator works
+t/op.sleep 15 See if sleep works
+t/op.split 7 See if split works
+t/op.sprintf 15 See if sprintf works
+t/op.stat 11 See if stat works
+t/op.study 14 See if study works
+t/op.subst 14 See if substitutions work
+t/op.time 14 See if time functions work
+t/op.unshift 15 See if unshift works
+t/re_tests 13 Input file for op.regexp
+toke.c 9 The tokener
+util.c 8 Utility routines
+util.h 15 Public declarations for the above
+version.c 15 Prints version of perl
+x2p/EXTERN.h 15 Same as above
+x2p/INTERN.h 15 Same as above
+x2p/Makefile.SH 4 Precursor to Makefile
+x2p/a2p.h 13 Global declarations
+x2p/a2p.man 12 Manual page for awk to perl translator
+x2p/a2p.y 12 A yacc grammer for awk
+x2p/a2py.c 9 Awk compiler, sort of
+x2p/handy.h 15 Handy definitions
+x2p/hash.c 13 Associative arrays again
+x2p/hash.h 14 Public declarations for the above
+x2p/s2p 10 Sed to perl translator
+x2p/s2p.man 9 Manual page for sed to perl translator
+x2p/str.c 11 String handling package
+x2p/str.h 15 Public declarations for the above
+x2p/util.c 13 Utility routines
+x2p/util.h 15 Public declarations for the above
+x2p/walk.c 7 Parse tree walker
View
75 Makefile.SH
@@ -6,7 +6,7 @@ case $CONFIG in
ln ../../../config.sh . || \
(echo "Can't find config.sh."; exit 1)
fi
- . config.sh
+ . ./config.sh
;;
esac
case "$0" in
@@ -20,31 +20,17 @@ esac
echo "Extracting Makefile (with variable substitutions)"
cat >Makefile <<!GROK!THIS!
-# $Header: Makefile.SH,v 1.0.1.5 88/02/02 11:20:49 root Exp $
+# $Header: Makefile.SH,v 2.0 88/06/05 00:07:54 root Exp $
#
# $Log: Makefile.SH,v $
-# Revision 1.0.1.5 88/02/02 11:20:49 root
-# patch13: added d_symlink dependency, changed TEST to ./perl TEST.
+# Revision 2.0 88/06/05 00:07:54 root
+# Baseline version 2.0.
#
-# Revision 1.0.1.4 88/01/28 10:17:59 root
-# patch8: added perldb.man
-#
-# Revision 1.0.1.3 88/01/26 14:14:52 root
-# Added mallocsrc stuff.
-#
-# Revision 1.0.1.2 88/01/26 08:46:04 root
-# patch 4: make depend didn't work right if . wasn't in PATH.
-#
-# Revision 1.0.1.1 88/01/24 03:55:18 root
-# patch 2: remove extra Log lines.
-#
-# Revision 1.0 87/12/18 16:11:50 root
-# Initial revision
#
CC = $cc
bin = $bin
-lib = $lib
+lib = $privlib
mansrc = $mansrc
manext = $manext
CFLAGS = $ccflags -O
@@ -71,17 +57,17 @@ util =
sh = Makefile.SH makedepend.SH
h1 = EXTERN.h INTERN.h arg.h array.h cmd.h config.h form.h handy.h
-h2 = hash.h perl.h search.h spat.h stab.h str.h util.h
+h2 = hash.h perl.h regexp.h spat.h stab.h str.h util.h
h = $(h1) $(h2)
-c1 = arg.c array.c cmd.c dump.c form.c hash.c $(mallocsrc)
-c2 = search.c stab.c str.c util.c version.c
+c1 = arg.c array.c cmd.c dump.c eval.c form.c hash.c $(mallocsrc)
+c2 = perly.c regexp.c stab.c str.c toke.c util.c version.c
c = $(c1) $(c2)
-obj1 = arg.o array.o cmd.o dump.o form.o hash.o $(mallocobj)
-obj2 = search.o stab.o str.o util.o version.o
+obj1 = arg.o array.o cmd.o dump.o eval.o form.o hash.o $(mallocobj)
+obj2 = perly.o regexp.o stab.o str.o toke.o util.o version.o
obj = $(obj1) $(obj2)
@@ -101,12 +87,13 @@ all: $(public) $(private) $(util)
perl: $(obj) perl.o
$(CC) $(LDFLAGS) $(LARGE) $(obj) perl.o $(libs) -o perl
-perl.c: perl.y
- @ echo Expect 2 shift/reduce errors...
- yacc perl.y
+perl.c perly.h: perl.y
+ @ echo Expect 37 shift/reduce errors...
+ yacc -d perl.y
mv y.tab.c perl.c
+ mv y.tab.h perly.h
-perl.o: perl.c perly.c perl.h EXTERN.h search.h util.h INTERN.h handy.h
+perl.o: perl.c perly.h perl.h EXTERN.h regexp.h util.h INTERN.h handy.h config.h
$(CC) -c $(CFLAGS) $(LARGE) perl.c
# if a .h file depends on another .h file...
@@ -119,23 +106,23 @@ perl.man: perl.man.1 perl.man.2
install: perl perl.man
# won't work with csh
export PATH || exit 1
- - mv $(bin)/perl $(bin)/perl.old
+ - mv $(bin)/perl $(bin)/perl.old 2>/dev/null
- if test `pwd` != $(bin); then cp $(public) $(bin); fi
cd $(bin); \
for pub in $(public); do \
-chmod 755 `basename $$pub`; \
+chmod +x `basename $$pub`; \
done
- - test $(bin) = /bin || rm -f /bin/perl
- - test $(bin) = /bin || ln -s $(bin)/perl /bin || cp $(bin)/perl /bin
-# chmod 755 makedir
-# - makedir `filexp $(lib)`
-# - \
-#if test `pwd` != `filexp $(lib)`; then \
-#cp $(private) `filexp $(lib)`; \
-#fi
-# cd `filexp $(lib)`; \
+ - test $(bin) = /usr/bin || rm -f /usr/bin/perl
+ - test $(bin) = /usr/bin || $(SLN) $(bin)/perl /usr/bin || cp $(bin)/perl /usr/bin
+ chmod +x makedir
+ - ./makedir $(lib)
+ - \
+if test `pwd` != $(lib); then \
+cp $(private) lib/*.pl $(lib); \
+fi
+# cd $(lib); \
#for priv in $(private); do \
-#chmod 755 `basename $$priv`; \
+#chmod +x `basename $$priv`; \
#done
- if test `pwd` != $(mansrc); then \
for page in $(manpages); do \
@@ -154,14 +141,16 @@ realclean:
# If the source file has a /*NOSTRICT*/ somewhere, ignore the lint message
# for that spot.
-lint:
- lint $(lintflags) $(defs) $(c) > perl.fuzz
+lint: perl.c $(c)
+ lint $(lintflags) $(defs) perl.c $(c) > perl.fuzz
depend: makedepend
+ - test -f perly.h || cp /dev/null perly.h
./makedepend
+ - test -s perly.h || /bin/rm -f perly.h
test: perl
- chmod 755 t/TEST t/base.* t/comp.* t/cmd.* t/io.* t/op.*
+ chmod +x t/TEST t/base.* t/comp.* t/cmd.* t/io.* t/op.*
cd t && (rm -f perl; $(SLN) ../perl .) && ./perl TEST
clist:
View
8 README
@@ -1,7 +1,7 @@
- Perl Kit, Version 1.0
+ Perl Kit, Version 2.0
- Copyright (c) 1987, Larry Wall
+ Copyright (c) 1988, Larry Wall
You may copy the perl kit in whole or in part as long as you don't try to
make money off it, or pretend that you wrote it.
@@ -52,7 +52,9 @@ Installation
This will run the regression tests on the perl you just made.
If it doesn't say "All tests successful" then something went wrong.
- See the README in the t subdirectory.
+ See the README in the t subdirectory. Note that you can't run it
+ in background if this disables opening of /dev/tty. If in doubt, just
+ cd to the t directory and run TEST by hand.
6) make install
View
1  Wishlist
@@ -2,4 +2,3 @@ date support
case statement
ioctl() support
random numbers
-directory reading via <>
View
2,170 arg.c
@@ -1,112 +1,168 @@
-/* $Header: arg.c,v 1.0.1.7 88/02/02 11:22:19 root Exp $
+/* $Header: arg.c,v 2.0 88/06/05 00:08:04 root Exp $
*
* $Log: arg.c,v $
- * Revision 1.0.1.7 88/02/02 11:22:19 root
- * patch13: fixed split(' ') to work right second time. Added CRYPT dependency.
- *
- * Revision 1.0.1.6 88/02/01 17:32:26 root
- * patch12: made split(' ') behave like awk in ignoring leading white space.
- *
- * Revision 1.0.1.5 88/01/30 08:53:16 root
- * patch9: fixed some missing right parens introduced (?) by patch 2
- *
- * Revision 1.0.1.4 88/01/28 10:22:06 root
- * patch8: added eval operator.
- *
- * Revision 1.0.1.2 88/01/24 03:52:34 root
- * patch 2: added STATBLKS dependencies.
- *
- * Revision 1.0.1.1 88/01/21 21:27:10 root
- * Now defines signal return values correctly using VOIDSIG.
- *
- * Revision 1.0 87/12/18 13:04:33 root
- * Initial revision
+ * Revision 2.0 88/06/05 00:08:04 root
+ * Baseline version 2.0.
*
*/
-#include <signal.h>
-#include "handy.h"
#include "EXTERN.h"
-#include "search.h"
-#include "util.h"
#include "perl.h"
-ARG *debarg;
+#include <signal.h>
+#include <errno.h>
+
+extern int errno;
-bool
-do_match(s,arg)
-register char *s;
+STR *
+do_match(arg,retary,sarg,ptrmaxsarg,sargoff,cushion)
register ARG *arg;
+STR ***retary;
+register STR **sarg;
+int *ptrmaxsarg;
+int sargoff;
+int cushion;
{
register SPAT *spat = arg[2].arg_ptr.arg_spat;
- register char *d;
register char *t;
+ register char *s = str_get(sarg[1]);
+ char *strend = s + sarg[1]->str_cur;
- if (!spat || !s)
- fatal("panic: do_match\n");
+ if (!spat)
+ return &str_yes;
+ if (!s)
+ fatal("panic: do_match");
+ if (retary) {
+ *retary = sarg; /* assume no match */
+ *ptrmaxsarg = sargoff;
+ }
if (spat->spat_flags & SPAT_USED) {
#ifdef DEBUGGING
if (debug & 8)
deb("2.SPAT USED\n");
#endif
- return FALSE;
+ return &str_no;
}
if (spat->spat_runtime) {
- t = str_get(eval(spat->spat_runtime,Null(STR***)));
+ t = str_get(eval(spat->spat_runtime,Null(STR***),-1));
#ifdef DEBUGGING
if (debug & 8)
deb("2.SPAT /%s/\n",t);
#endif
- if (d = compile(&spat->spat_compex,t,TRUE,FALSE)) {
-#ifdef DEBUGGING
- deb("/%s/: %s\n", t, d);
-#endif
- return FALSE;
- }
- if (spat->spat_compex.complen <= 1 && curspat)
- spat = curspat;
- if (execute(&spat->spat_compex, s, TRUE, 0)) {
- if (spat->spat_compex.numsubs)
+ spat->spat_regexp = regcomp(t,spat->spat_flags & SPAT_FOLD,1);
+ if (!*spat->spat_regexp->precomp && lastspat)
+ spat = lastspat;
+ if (regexec(spat->spat_regexp, s, strend, TRUE, 0,
+ sarg[1]->str_pok & 4 ? sarg[1] : Nullstr)) {
+ if (spat->spat_regexp->subbase)
curspat = spat;
- return TRUE;
+ lastspat = spat;
+ goto gotcha;
}
else
- return FALSE;
+ return &str_no;
}
else {
#ifdef DEBUGGING
if (debug & 8) {
char ch;
- if (spat->spat_flags & SPAT_USE_ONCE)
+ if (spat->spat_flags & SPAT_ONCE)
ch = '?';
else
ch = '/';
- deb("2.SPAT %c%s%c\n",ch,spat->spat_compex.precomp,ch);
+ deb("2.SPAT %c%s%c\n",ch,spat->spat_regexp->precomp,ch);
}
#endif
- if (spat->spat_compex.complen <= 1 && curspat)
- spat = curspat;
- if (spat->spat_first) {
+ if (!*spat->spat_regexp->precomp && lastspat)
+ spat = lastspat;
+ t = s;
+ if (hint) {
+ if (hint < s || hint > strend)
+ fatal("panic: hint in do_match");
+ s = hint;
+ hint = Nullch;
+ if (spat->spat_regexp->regback >= 0) {
+ s -= spat->spat_regexp->regback;
+ if (s < t)
+ s = t;
+ }
+ else
+ s = t;
+ }
+ else if (spat->spat_short) {
if (spat->spat_flags & SPAT_SCANFIRST) {
- str_free(spat->spat_first);
- spat->spat_first = Nullstr; /* disable optimization */
+ if (sarg[1]->str_pok == 5) {
+ if (screamfirst[spat->spat_short->str_rare] < 0)
+ goto nope;
+ else if (!(s = screaminstr(sarg[1],spat->spat_short)))
+ goto nope;
+ else if (spat->spat_flags & SPAT_ALL)
+ goto yup;
+ }
+ else if (!(s = fbminstr(s, strend, spat->spat_short)))
+ goto nope;
+ else if (spat->spat_flags & SPAT_ALL)
+ goto yup;
+ else if (spat->spat_regexp->regback >= 0) {
+ ++*(long*)&spat->spat_short->str_nval;
+ s -= spat->spat_regexp->regback;
+ if (s < t)
+ s = t;
+ }
+ else
+ s = t;
+ }
+ else if (!multiline && (*spat->spat_short->str_ptr != *s ||
+ strnNE(spat->spat_short->str_ptr, s, spat->spat_slen) ))
+ goto nope;
+ if (--*(long*)&spat->spat_short->str_nval < 0) {
+ str_free(spat->spat_short);
+ spat->spat_short = Nullstr; /* opt is being useless */
}
- else if (*spat->spat_first->str_ptr != *s ||
- strnNE(spat->spat_first->str_ptr, s, spat->spat_flen) )
- return FALSE;
}
- if (execute(&spat->spat_compex, s, TRUE, 0)) {
- if (spat->spat_compex.numsubs)
+ if (regexec(spat->spat_regexp, s, strend, s == t, 0,
+ sarg[1]->str_pok & 4 ? sarg[1] : Nullstr)) {
+ if (spat->spat_regexp->subbase)
curspat = spat;
- if (spat->spat_flags & SPAT_USE_ONCE)
+ lastspat = spat;
+ if (spat->spat_flags & SPAT_ONCE)
spat->spat_flags |= SPAT_USED;
- return TRUE;
+ goto gotcha;
}
else
- return FALSE;
+ return &str_no;
}
/*NOTREACHED*/
+
+ gotcha:
+ if (retary && curspat == spat) {
+ int iters, i, len;
+
+ iters = spat->spat_regexp->nparens;
+ *ptrmaxsarg = iters + sargoff;
+ sarg = (STR**)saferealloc((char*)(sarg - sargoff),
+ (iters+2+cushion+sargoff)*sizeof(STR*)) + sargoff;
+
+ for (i = 1; i <= iters; i++) {
+ sarg[i] = str_static(&str_no);
+ if (s = spat->spat_regexp->startp[i]) {
+ len = spat->spat_regexp->endp[i] - s;
+ if (len > 0)
+ str_nset(sarg[i],s,len);
+ }
+ }
+ *retary = sarg;
+ }
+ return &str_yes;
+
+yup:
+ ++*(long*)&spat->spat_short->str_nval;
+ return &str_yes;
+
+nope:
+ ++*(long*)&spat->spat_short->str_nval;
+ return &str_no;
}
int
@@ -116,63 +172,96 @@ register ARG *arg;
{
register SPAT *spat;
register STR *dstr;
- register char *s;
+ register char *s = str_get(str);
+ char *strend = s + str->str_cur;
register char *m;
spat = arg[2].arg_ptr.arg_spat;
- s = str_get(str);
if (!spat || !s)
- fatal("panic: do_subst\n");
+ fatal("panic: do_subst");
else if (spat->spat_runtime) {
- char *d;
-
- m = str_get(eval(spat->spat_runtime,Null(STR***)));
- if (d = compile(&spat->spat_compex,m,TRUE,FALSE)) {
-#ifdef DEBUGGING
- deb("/%s/: %s\n", m, d);
-#endif
- return 0;
- }
+ m = str_get(eval(spat->spat_runtime,Null(STR***),-1));
+ spat->spat_regexp = regcomp(m,spat->spat_flags & SPAT_FOLD,1);
}
#ifdef DEBUGGING
if (debug & 8) {
- deb("2.SPAT /%s/\n",spat->spat_compex.precomp);
+ deb("2.SPAT /%s/\n",spat->spat_regexp->precomp);
}
#endif
- if (spat->spat_compex.complen <= 1 && curspat)
- spat = curspat;
- if (spat->spat_first) {
+ if (!*spat->spat_regexp->precomp && lastspat)
+ spat = lastspat;
+ m = s;
+ if (hint) {
+ if (hint < s || hint > strend)
+ fatal("panic: hint in do_match");
+ s = hint;
+ hint = Nullch;
+ if (spat->spat_regexp->regback >= 0) {
+ s -= spat->spat_regexp->regback;
+ if (s < m)
+ s = m;
+ }
+ else
+ s = m;
+ }
+ else if (spat->spat_short) {
if (spat->spat_flags & SPAT_SCANFIRST) {
- str_free(spat->spat_first);
- spat->spat_first = Nullstr; /* disable optimization */
+ if (str->str_pok == 5) {
+ if (screamfirst[spat->spat_short->str_rare] < 0)
+ goto nope;
+ else if (!(s = screaminstr(str,spat->spat_short)))
+ goto nope;
+ }
+ else if (!(s = fbminstr(s, strend, spat->spat_short)))
+ goto nope;
+ else if (spat->spat_regexp->regback >= 0) {
+ ++*(long*)&spat->spat_short->str_nval;
+ s -= spat->spat_regexp->regback;
+ if (s < m)
+ s = m;
+ }
+ else
+ s = m;
+ }
+ else if (!multiline && (*spat->spat_short->str_ptr != *s ||
+ strnNE(spat->spat_short->str_ptr, s, spat->spat_slen) ))
+ goto nope;
+ if (--*(long*)&spat->spat_short->str_nval < 0) {
+ str_free(spat->spat_short);
+ spat->spat_short = Nullstr; /* opt is being useless */
}
- else if (*spat->spat_first->str_ptr != *s ||
- strnNE(spat->spat_first->str_ptr, s, spat->spat_flen) )
- return 0;
}
- if (m = execute(&spat->spat_compex, s, TRUE, 1)) {
+ if (regexec(spat->spat_regexp, s, strend, s == m, 1,
+ str->str_pok & 4 ? str : Nullstr)) {
int iters = 0;
dstr = str_new(str_len(str));
- if (spat->spat_compex.numsubs)
+ str_nset(dstr,m,s-m);
+ if (spat->spat_regexp->subbase)
curspat = spat;
+ lastspat = spat;
do {
+ m = spat->spat_regexp->startp[0];
if (iters++ > 10000)
- fatal("Substitution loop?\n");
- if (spat->spat_compex.numsubs)
- s = spat->spat_compex.subbase;
+ fatal("Substitution loop");
+ if (spat->spat_regexp->subbase)
+ s = spat->spat_regexp->subbase;
str_ncat(dstr,s,m-s);
- s = spat->spat_compex.subend[0];
- str_scat(dstr,eval(spat->spat_repl,Null(STR***)));
- if (spat->spat_flags & SPAT_USE_ONCE)
+ s = spat->spat_regexp->endp[0];
+ str_scat(dstr,eval(spat->spat_repl,Null(STR***),-1));
+ if (spat->spat_flags & SPAT_ONCE)
break;
- } while (m = execute(&spat->spat_compex, s, FALSE, 1));
+ } while (regexec(spat->spat_regexp, s, strend, FALSE, 1, Nullstr));
str_cat(dstr,s);
str_replace(str,dstr);
STABSET(str);
return iters;
}
return 0;
+
+nope:
+ ++*(long*)&spat->spat_short->str_nval;
+ return 0;
}
int
@@ -188,7 +277,7 @@ register ARG *arg;
tbl = arg[2].arg_ptr.arg_cval;
s = str_get(str);
if (!tbl || !s)
- fatal("panic: do_trans\n");
+ fatal("panic: do_trans");
#ifdef DEBUGGING
if (debug & 8) {
deb("2.TBL\n");
@@ -206,28 +295,29 @@ register ARG *arg;
}
int
-do_split(s,spat,retary)
-register char *s;
+do_split(spat,retary,sarg,ptrmaxsarg,sargoff,cushion)
register SPAT *spat;
STR ***retary;
+register STR **sarg;
+int *ptrmaxsarg;
+int sargoff;
+int cushion;
{
+ register char *s = str_get(sarg[1]);
+ char *strend = s + sarg[1]->str_cur;
register STR *dstr;
register char *m;
register ARRAY *ary;
static ARRAY *myarray = Null(ARRAY*);
int iters = 0;
- STR **sarg;
- register char *e;
int i;
if (!spat || !s)
- fatal("panic: do_split\n");
+ fatal("panic: do_split");
else if (spat->spat_runtime) {
- char *d;
-
- m = str_get(eval(spat->spat_runtime,Null(STR***)));
+ m = str_get(eval(spat->spat_runtime,Null(STR***),-1));
if (!*m || (*m == ' ' && !m[1])) {
- m = "[ \\t\\n]+";
+ m = "\\s+";
spat->spat_flags |= SPAT_SKIPWHITE;
}
if (spat->spat_runtime->arg_type == O_ITEM &&
@@ -235,16 +325,11 @@ STR ***retary;
arg_free(spat->spat_runtime); /* it won't change, so */
spat->spat_runtime = Nullarg; /* no point compiling again */
}
- if (d = compile(&spat->spat_compex,m,TRUE,FALSE)) {
-#ifdef DEBUGGING
- deb("/%s/: %s\n", m, d);
-#endif
- return FALSE;
- }
+ spat->spat_regexp = regcomp(m,spat->spat_flags & SPAT_FOLD,1);
}
#ifdef DEBUGGING
if (debug & 8) {
- deb("2.SPAT /%s/\n",spat->spat_compex.precomp);
+ deb("2.SPAT /%s/\n",spat->spat_regexp->precomp);
}
#endif
if (retary)
@@ -252,21 +337,36 @@ STR ***retary;
else
ary = spat->spat_repl[1].arg_ptr.arg_stab->stab_array;
if (!ary)
- myarray = ary = anew();
+ myarray = ary = anew(Nullstab);
ary->ary_fill = -1;
if (spat->spat_flags & SPAT_SKIPWHITE) {
while (isspace(*s))
s++;
}
- while (*s && (m = execute(&spat->spat_compex, s, (iters == 0), 1))) {
- if (spat->spat_compex.numsubs)
- s = spat->spat_compex.subbase;
- dstr = str_new(m-s);
- str_nset(dstr,s,m-s);
- astore(ary, iters++, dstr);
- if (iters > 10000)
- fatal("Substitution loop?\n");
- s = spat->spat_compex.subend[0];
+ if (spat->spat_short) {
+ i = spat->spat_short->str_cur;
+ while (*s && (m = fbminstr(s, strend, spat->spat_short))) {
+ dstr = str_new(m-s);
+ str_nset(dstr,s,m-s);
+ astore(ary, iters++, dstr);
+ if (iters > 10000)
+ fatal("Substitution loop");
+ s = m + i;
+ }
+ }
+ else {
+ while (*s && regexec(spat->spat_regexp, s, strend, (iters == 0), 1,
+ Nullstr)) {
+ m = spat->spat_regexp->startp[0];
+ if (spat->spat_regexp->subbase)
+ s = spat->spat_regexp->subbase;
+ dstr = str_new(m-s);
+ str_nset(dstr,s,m-s);
+ astore(ary, iters++, dstr);
+ if (iters > 10000)
+ fatal("Substitution loop");
+ s = spat->spat_regexp->endp[0];
+ }
}
if (*s) { /* ignore field after final "whitespace" */
dstr = str_new(0); /* if they interpolate, it's null anyway */
@@ -278,10 +378,10 @@ STR ***retary;
iters--;
}
if (retary) {
- sarg = (STR**)safemalloc((iters+2)*sizeof(STR*));
+ *ptrmaxsarg = iters + sargoff;
+ sarg = (STR**)saferealloc((char*)(sarg - sargoff),
+ (iters+2+cushion+sargoff)*sizeof(STR*)) + sargoff;
- sarg[0] = Nullstr;
- sarg[iters+1] = Nullstr;
for (i = 1; i <= iters; i++)
sarg[i] = afetch(ary,i-1);
*retary = sarg;
@@ -297,12 +397,14 @@ register STR *str;
{
STR **tmpary; /* must not be register */
register STR **elem;
+ register int items;
- (void)eval(arg[2].arg_ptr.arg_arg,&tmpary);
+ (void)eval(arg[2].arg_ptr.arg_arg,&tmpary,-1);
+ items = (int)str_gnum(*tmpary);
elem = tmpary+1;
- if (*elem)
- str_sset(str,*elem++);
- for (; *elem; elem++) {
+ if (items-- > 0)
+ str_sset(str,*elem++);
+ for (; items > 0; items--,elem++) {
str_cat(str,delim);
str_scat(str,*elem);
}
@@ -310,6 +412,49 @@ register STR *str;
safefree((char*)tmpary);
}
+FILE *
+forkopen(name,mode)
+char *name;
+char *mode;
+{
+ int pfd[2];
+
+ if (pipe(pfd) < 0)
+ return Nullfp;
+ while ((forkprocess = fork()) == -1) {
+ if (errno != EAGAIN)
+ return Nullfp;
+ sleep(5);
+ }
+ if (*mode == 'w') {
+ if (forkprocess) {
+ close(pfd[0]);
+ return fdopen(pfd[1],"w");
+ }
+ else {
+ close(pfd[1]);
+ close(0);
+ dup(pfd[0]); /* substitute our pipe for stdin */
+ close(pfd[0]);
+ return Nullfp;
+ }
+ }
+ else {
+ if (forkprocess) {
+ close(pfd[1]);
+ return fdopen(pfd[0],"r");
+ }
+ else {
+ close(pfd[0]);
+ close(1);
+ if (dup(pfd[1]) == 0)
+ dup(pfd[1]); /* substitute our pipe for stdout */
+ close(pfd[1]);
+ return Nullfp;
+ }
+ }
+}
+
bool
do_open(stab,name)
STAB *stab;
@@ -318,27 +463,61 @@ register char *name;
FILE *fp;
int len = strlen(name);
register STIO *stio = stab->stab_io;
+ char *myname = savestr(name);
+ int result;
+ int fd;
+ name = myname;
+ forkprocess = 1; /* assume true if no fork */
while (len && isspace(name[len-1]))
name[--len] = '\0';
if (!stio)
stio = stab->stab_io = stio_new();
if (stio->fp) {
+ fd = fileno(stio->fp);
if (stio->type == '|')
- pclose(stio->fp);
+ result = pclose(stio->fp);
else if (stio->type != '-')
- fclose(stio->fp);
+ result = fclose(stio->fp);
+ else
+ result = 0;
+ if (result == EOF && fd > 2)
+ fprintf(stderr,"Warning: unable to close filehandle %s properly.\n",
+ stab->stab_name);
stio->fp = Nullfp;
}
stio->type = *name;
if (*name == '|') {
for (name++; isspace(*name); name++) ;
- fp = popen(name,"w");
+ if (strNE(name,"-"))
+ fp = popen(name,"w");
+ else {
+ fp = forkopen(name,"w");
+ stio->subprocess = forkprocess;
+ stio->type = '%';
+ }
}
else if (*name == '>' && name[1] == '>') {
+ stio->type = 'a';
for (name += 2; isspace(*name); name++) ;
fp = fopen(name,"a");
}
+ else if (*name == '>' && name[1] == '&') {
+ for (name += 2; isspace(*name); name++) ;
+ if (isdigit(*name))
+ fd = atoi(name);
+ else {
+ stab = stabent(name,FALSE);
+ if (stab->stab_io && stab->stab_io->fp) {
+ fd = fileno(stab->stab_io->fp);
+ stio->type = stab->stab_io->type;
+ }
+ else
+ fd = -1;
+ }
+ fp = fdopen(dup(fd),stio->type == 'a' ? "a" :
+ (stio->type == '<' ? "r" : "w") );
+ }
else if (*name == '>') {
for (name++; isspace(*name); name++) ;
if (strEQ(name,"-")) {
@@ -363,8 +542,15 @@ register char *name;
while (len && isspace(name[len-1]))
name[--len] = '\0';
for (; isspace(*name); name++) ;
- fp = popen(name,"r");
- stio->type = '|';
+ if (strNE(name,"-")) {
+ fp = popen(name,"r");
+ stio->type = '|';
+ }
+ else {
+ fp = forkopen(name,"r");
+ stio->subprocess = forkprocess;
+ stio->type = '%';
+ }
}
else {
stio->type = '<';
@@ -377,9 +563,11 @@ register char *name;
fp = fopen(name,"r");
}
}
+ safefree(myname);
if (!fp)
return FALSE;
- if (stio->type != '|' && stio->type != '-') {
+ if (stio->type &&
+ stio->type != '|' && stio->type != '-' && stio->type != '%') {
if (fstat(fileno(fp),&statbuf) < 0) {
fclose(fp);
return FALSE;
@@ -400,14 +588,18 @@ register STAB *stab;
{
register STR *str;
char *oldname;
+ int filemode,fileuid,filegid;
- while (alen(stab->stab_array) >= 0L) {
+ while (alen(stab->stab_array) >= 0) {
str = ashift(stab->stab_array);
str_sset(stab->stab_val,str);
STABSET(stab->stab_val);
oldname = str_get(stab->stab_val);
if (do_open(stab,oldname)) {
if (inplace) {
+ filemode = statbuf.st_mode;
+ fileuid = statbuf.st_uid;
+ filegid = statbuf.st_gid;
if (*inplace) {
str_cat(str,inplace);
#ifdef RENAME
@@ -418,9 +610,23 @@ register STAB *stab;
UNLINK(oldname);
#endif
}
+ else {
+ UNLINK(oldname);
+ }
sprintf(tokenbuf,">%s",oldname);
+ errno = 0; /* in case sprintf set errno */
do_open(argvoutstab,tokenbuf);
defoutstab = argvoutstab;
+#ifdef FCHMOD
+ fchmod(fileno(argvoutstab->stab_io->fp),filemode);
+#else
+ chmod(oldname,filemode);
+#endif
+#ifdef FCHOWN
+ fchown(fileno(argvoutstab->stab_io->fp),fileuid,filegid);
+#else
+ chown(oldname,fileuid,filegid);
+#endif
}
str_free(str);
return stab->stab_io->fp;
@@ -443,16 +649,30 @@ bool explicit;
{
bool retval = FALSE;
register STIO *stio = stab->stab_io;
+ int status;
+ int tmp;
- if (!stio) /* never opened */
+ if (!stio) { /* never opened */
+ if (dowarn && explicit)
+ warn("Close on unopened file <%s>",stab->stab_name);
return FALSE;
+ }
if (stio->fp) {
if (stio->type == '|')
retval = (pclose(stio->fp) >= 0);
else if (stio->type == '-')
retval = TRUE;
- else
+ else {
retval = (fclose(stio->fp) != EOF);
+ if (stio->type == '%' && stio->subprocess) {
+ while ((tmp = wait(&status)) != stio->subprocess && tmp != -1)
+ ;
+ if (tmp == -1)
+ statusvalue = -1;
+ else
+ statusvalue = (unsigned)status & 0xffff;
+ }
+ }
stio->fp = Nullfp;
}
if (explicit)
@@ -468,10 +688,11 @@ STAB *stab;
register STIO *stio;
int ch;
- if (!stab)
- return TRUE;
+ if (!stab) /* eof() */
+ stio = argvstab->stab_io;
+ else
+ stio = stab->stab_io;
- stio = stab->stab_io;
if (!stio)
return TRUE;
@@ -487,8 +708,8 @@ STAB *stab;
ungetc(ch, stio->fp);
return FALSE;
}
- if