[comp.sources.bugs] perl 3.0 patch #9

lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) (03/02/90)

System: perl version 3.0
Patch #: 9
Priority: HIGH
Subject: Configure now determines whether volatile is supported
Subject: libBSD.a and libPW.a are now supported
Subject: Configure was executing "try" from some other directory
Subject: -DLANGUAGE_C now found on mips machines
Subject: some libraries were getting names extracted twice
Subject: yet more output formats for nm
Subject: some standard stdio's weren't considered so
Subject: Configure now prompts correctly for bison -y
Subject: extraneous $ on suidperl in Makefile
Subject: in README, documented more weirdities on various machines
Subject: added pipe function
Subject: volatilized some more variables for super-optimizing compilers
Subject: nested foreach loops didn't reset inner loop on next to outer loop
Subject: returned values were read from obsolete stack
Subject: added sanity check on longjmp() return value
Subject: substitutions that almost always succeed can corrupt label stack
Subject: subs which return by both mechanisms can clobber local return data
Subject: changed internal SUB label to _SUB_
Subject: line numbers were bogus during certain portions of foreach evaluation
Subject: the x operator is now up to 10 times faster
Subject: @_ clobbered by ($foo,$bar) = split
Subject: split now can split into more than 10000 elements
Subject: sped up pack and unpack
Subject: pack of unsigned ints and longs blew up some places
Subject: sun3 can't cast negative float to unsigned int or long
Subject: local($.) didn't work
Subject: grep(s/foo/bar/, @abc = @xyz) modified @xyz rather than @abc
Subject: syscall returned stack size rather than value of system call
Subject: open(FOO,"$filename\0") will now protect trailing spaces in filename
Subject: removed obsolete checks to avoid opening block devices
Subject: removed references to acusec and modusec that some utime.h's have
Subject: unpack of single item now works in a scalar context
Subject: slices ignored value of $[
Subject: grep now returns number of items matched in scalar context
Subject: grep iterations no longer in the regexp context of previous iteration
Subject: documented PD status of sample Perl scripts in eg/
Subject: some perl code caught by shift in shift semantics
Subject: rename command can now default to *
Subject: added relink command
Subject: added travesty program
Subject: a return in scalar context wouldn't return array
Subject: !~ now always returns scalar even in array context
Subject: some machines can't cast float to long with high bit set
Subject: piped opens returned undef in child
Subject: @array in scalar context now returns length of array
Subject: chdir; coredumped
Subject: wait no longer ignores signals
Subject: mkdir now handles odd versions of /bin/mkdir
Subject: -l FILEHANDLE now disallowed
Subject: $#foo -= 2 didn't work
Subject: ... in format threw off subsequent field
Subject: abbrev.pl didn't work if $[ != 0
Subject: complete.pl didn't work if $[ != 0
Subject: getopt.pl didn't work if $[ != 0
Subject: getopts.pl didn't work if $[ != 0
Subject: Getopt didn't return meaningful value
Subject: look.pl was busted
Subject: in termcap.pl, Tgoto was documented wrong
Subject: in termcap.pl, Tgetent could loop endlessly
Subject: in termcap.pl, ^x not handled right
Subject: in termcap.pl, @_ no longer used as temp array
Subject: unused VREG symbol deleted
Subject: perl can now start up other interpreters scripts  
Subject: you may now undef $/ to have no input record separator
Subject: nested evals clobbered their longjmp environment
Subject: in manual, example of open and ?: was backwards
Subject: documented in-place modification capabilites of grep
Subject: documented how to handle arbitrary weird characters in filenames
Subject: documented the unflushed buffers problem on piped opens
Subject: documented how to force top of page
Subject: $0 is now always the command name
Subject: perl can now start up other interpreters scripts
Subject: eval could mistakenly return undef in array context
Subject: /[\200-\377]/ didn't work on machines with signed chars
Subject: \d, \w, and \s could misfire on characters with high bit set
Subject: /\bfoo/i didn't work
Subject: sometimes perl thought ordinary data was a symbol table entry
Subject: stab_array() and stab_hash() weren't defined on MICROPORT
Subject: insufficient space allocated for numeric string on sun4
Subject: underscore in an array name in a double-quoted string not recognized
Subject: "@foo{}" not recognized unless @foo defined
Subject: "$foo[$[]" gives error
Subject: "${1}" didn't work
Subject: base.term now checks that /dev/null is character special
Subject: op.stat could exceed shell's max arg length
Subject: return grandfathered to never be function call
Subject: non-existent perldb.pl now gives reasonable error message
Subject: null hereis core dumped
Subject: fbminstr() called instr() rather than ninstr()
Subject: piped opens returned undefined rather than 0 in child
Subject: a2p didn't allow logical expressions everywhere it should
Subject: a2p.h had bzero() definition depending on BCOPY
Subject: s2p didn't handle \< and \>
Subject: a2p didn't put a $ on ExitValue

Description:
	Well, I didn't quite fix 100 things--only 94.  There are still
	some other things to do, so don't think if I didn't fix your
	favorite bug that your bug report is in the bit bucket.  (It
	may be, but don't think it.  :-)

	There are very few enhancements here.  One is the new pipe()
	function.  There was just no way to emulate this using the
	current operations, unless you happened to have socketpair()
	on your system.  Not even syscall() was useful in this respect.

	Configure now determines whether volatile is supported, since
	some compilers implement volatile but don't define __STDC__.
	Some compilers can put structure members and global variables
	into registers, so more variables had to be declared volatile
	to avoid clobbering during longjmp().

	Some systems have wanted routines stashed away in libBSD.a and
	libPW.a.  Configure can now find them.

	A number of Configure tests create a file called "try" and then
	execute it.  Unfortunately, if there was a "try" elsewhere in PATH
	it got that one instead.  All references are now to "./try".

	On Ultrix machines running the Mips cpu, some header files define
	things differently for assembly language than for the C language.
	To differentiate these, cc passes a -DLANGUAGE_C to the C preprocessor.
	Unfortunately, Configure, makedepend and perl want to use the 
	preprocessor independently of cc.  Configure now defaults to
	adding -DLANGUAGE_C on machines containing that symbol in signal.h.

	In Configure, some libraries were getting into the list more than
	once, causing extra extraction overhead.  The names are now
	uniquified.

	Someone has invented yet another output format for nm.  Sigh.
	Why do people assume that only people read the output of programs?

	Due to commentary between a declaration and its semicolon, some
	standard versions of stdio weren't being considered standard, and the
	type of char used by stdio was being misidentified.

	People trying to use bison instead of yacc ran into two problems.
	One, lack of alloca(), is solved on some machines by finding libPW.a.
	The other is that you have to supply a -y switch to bison to get
	it to emulate yacc naming conventions.  Configure now prompts
	correctly for bison -y.

	The make clean had a rm -f $suidperl where it just wanted
	a rm -f suidperl

	In the README, documented more weirdities on various machines,
	including a pointer to the JMPCLOBBER symbol.

	In the construct
		OUTER: foreach (1,2,3) {
		    INNER: foreach (4,5) {
			...
			next OUTER;
		    }
		}
	the inner loop was not getting reset to the first element.  This
	was one of those bugs that arise because longjmp() doesn't
	execute exit handlers as it unwinds the stack.

	Perl reallocs many things as they grow, including the stack (its
	stack, not the C program's stack).  This means that routines
	have to be careful to retreive the new stack when they call
	subroutines that can do such a realloc.  In cmd.c there was
	such code but it was hidden inside an #ifdef JMPCLOBBER that
	it should have been outside of, so you could get bad return
	values of JMPCLOBBER wasn't defined.  If you defined JMPCLOBBER
	to work around this problem, you should consider undefining
	it if your compiler guarantees that register variables get the value
	they had either at setjmp() or longjmp() time.  Perl runs
	slightly faster without JMPCLOBBER defined.

	The longjmp()s that perl does return known values, but as a
	paranoid programming measure, it now checks that the values
	are one of the expected ones.

	If you say something like
		while (s/ /_/) {}
	the substitution almost always succeeds (on normal text).  There
	is an optimization that quickly discovers and bypasses operations
	that are going to fail, but does nothing to help generally successful
	ones such as the one above.  So there's a heuristic that disables
	the optimization if it isn't buying us anything.  Unfortunately,
	in the above case, it's in the conditional of a while loop,
	which is duplicated by another optimization to be a
		last unless s/ /_/;
	at the end of the loop, to avoid unnecessary subroutine calls.
	Because the conditional was duplicated (not the expression itself,
	just the structure pointing to it), the heuristic mentioned above
	tried to disable the first optimization twice, resulting in the
	label stack getting corrupted.

	Some subroutines which mix both return mechanisms like this:
		sub foo {
		    local($foo);
		    return $foo if $whatever;
		    $foo;
		}
	This clobbered the return value of $foo when the end of the scope
	of the local($foo) was reached.  This was because such a routine
	turns into something like this internally:
		sub foo {
		    _SUB_: {
			local($foo);
			if ($whatever) {
			    $foo; last _SUB_;
			}
			$foo;
		    }
		}
	Because the outer _SUB_ block was manufactured by non-standard
	means, it wasn't getting marked as an expression that could
	return a value, ie a terminal expression.  So the return value
	wasn't getting properly saved off to the side before the local()
	exited.
		    
	The internal label on subroutine blocks used to be SUB, but I
	changed it to _SUB_ to avoid possible confusion.  Evals now have
	labels too, so they are labelled with _EVAL_.  The reason evals
	now have a label is that nested evals need separate longjmp
	environments, or fatal errors end up getting a longjmp() botch.
	So eval now uses the same label stack as loops and subroutines.

	The eval routine used to always return undef on failure.  In an
	array context, however, this makes a non-null array, which when
	assigned is TRUE, which is counter-intuitive.  It now returns
	a null array upon failure in an array context.

	When a foreach operator works on a non-array, the compiler translates
		foreach (1,2,3) {
	into something like
		@_GEN_0 = (1,2,3); foreach (@_GEN_0) {
	Unfortunately, the line number was not correctly propagated to both
	command structures, so huge line numbers could appear in error
	messages and while debugging.

	The x operator was stupidly written, just calling the internal
	routine str_scat() multiple times, and not preextending the
	string to the known new length.  It now preextends the string
	and calls a special routine to replicate the string quickly.
	On long strings like '\0' x 1024, the operator is more than
	10 times faster.

	The split operator is supposed to split into @_ if called in
	a scalar context.  Unfortunately, it was also splitting into @_
	in an array context that wasn't a real array, such as assignment
	to a list:
	    ($foo,$bar) = split;
	This has now been fixed.

	The split and substitute operators have a check to make sure
	that it isn't looping endlessly.  Unfortunate, they had a hardwired
	limit of 10000 iterations.  There are applications conceivable
	where you could work on longer values than that, so they
	now calculate a reasonable limit based on the length of the arguments.

	Pack and unpack called atoi all the time on the template fields.
	Since there are usually at most one or two digits of number,
	this wasted a lot of time on machines with slow subroutine calls.
	It now picks up the number itself.

	There were several places that casts could blow up.  In particular,
	it appears that a sun3 can't cast a negative float to an unsigned
	integer.  Appropriate measure have been taken--hopefully this
	won't blow someone else up.

	A local($.) didn't work right because the actual value of the
	current line number is derived from the last input filehandle.
	This has been fixed by causing the last input filehandle to
	be restored after the scope of a local($.) to what it was when
	the local was executed.

	Assignment is supposed to return the final value of the left
	hand side.  In the case of array assignment (in an array context),
	it was actually returning the right hand side.  This showed up in
	things that referred to the actual elements of an array value,
	such as grep(s/foo/bar/, @abc = @xyz), which modified @xyz rather
	than @abc.

	The syscall() function was returning a garbage value (the index of
	the top of the stack, actually) rather than value of system call.

	There was some discussion about how to open files with arbitrary
	characters in the filename.  In particular, the open function strips
	trailing spaces.  There was no way to suppress this.  Now you can
	put an explicit null at the end of the string
	    open(FOO,"$filename\0")
	and this will hide any spaces on the end of the filename.  The Unix
	open() function will of course treat the null as the trailing delimiter.

	As a hangover from when Perl was not useful on binary files, there
	was a check to make sure that the file being opened was a normal
	file or character special file or socket.  Now that Perl can
	handle binary data, this is useless, and has been removed.

	Some versions of utime.h have microseconds specified as acusec and
	modusec.  Perl was referring to these in order to zero out the
	fields.  But not everyone has these.  Perl now just bzero's out
	the structure and refers only to fields that everyone has.

	You used to have to say
		($foo) = unpack("L",$bar);
	Now you can say
		$foo = unpack("L",$bar);
	and it will just unpack the first thing specified by the template;

	The subscripts for slices were ignoring the value of $[.  (This
	never made any difference for people who leave $[ set to 0.)

	It seems reasonable that grep in a scalar context should return the
	number of items matched so that it can be used in, say, a conditional.
	Formerly it returned an undef.

	Another problem with grep was that if you said something like
		grep(/$1/, @foo)
	then each iteration of grep was executing in the context of the
	previous iteration's regexp, so $1 might be wiped out after the
	first iteration.  All iterations of grep now operate in the regexp
	context of the grep operator itself.
		
	The eg/README file now explicity states that the examples in
	the eg directory are to be considered in the Public Domain, and
	thus do not have the same restrictions as the Perl source.

	In a previous patch the shift operator was made to shift @_ inside
	of subroutines.  This made some of the getopt code wrong.

	The sample rename command (and the new relink command) can either
	take a list of filenames from stdin, or if stdin is a terminal,
	default to a * in the current directory.

	A sample travesty program is now included.  If you want to know what
	it does, feed it about 10 Usenet articles, or the perl manual, and
	see what it prints out.

	If a return operator was embedded in an expression that supplied
	a scalar context, but the subroutine containing the return was
	called in an array context, an array was not returned correctly.
	Now it is.

	The !~ operator used to ignore the negation in an array context and
	do the same thing as =~.  It now always returns scalar even in
	array context, so if you say
		($foo) = ($bar !~ /(pat)/)
	$foo will get a value of either 1 or ''.

	Opens on pipes were defined to return the child's pid in the parent,
	and FALSE in the child.  Unfortunately, what the child actually
	got was an undef, making it indistinguishable from a failure to
	open the pipe successfully.  The child now gets a 0, and undef
	means a failure to fork a child.

	Formerly, @array in a scalar context returned the last value of
	the array, by analogy to the comma operator.  This makes for
	counter-intuitive results when you say
		if (@array)
	if 0 or '' is a legal array value.  @array now returns the length
	of the array (not the subscript of the last element, which is @#array).
	To get the last element of the array you must either pop(@array) or
	refer to $array[$#array].

	The chdir operator with no argument was supposed to change directory
	to your home directory, but it core dumped instead.

	The wait operator was ignoring SIGINT and SIGQUIT, by analogy to
	the system and pipe operations.  But wait is a lower level operation,
	and it gives you more freedom if those signals aren't automatically
	ignored.  If you want them ignored, you now have to explicitly
	ignore them by setting the proper %SIG entry.

	Different versions of /bin/mkdir and /bin/rmdir return different
	messages upon failure.  Perl now knows about more of them.

	-l FILEHANDLE now disallowed
	The use of the -l file test makes no sense on a filehandle, since
	you can't open symbolic links.  So -l FILEHANDLE now is a fatal
	error.  This also means you can't say -l _, which is also a
	useless operation.

	The heavy wizardry involved in saying $#foo -= 2 didn't work quite
	right.

	In formats, you can say ... in a ^ field to have ... output when
	there is more for that field that is getting truncated.  The
	next field was getting shifted over by three characters, however.

	The perl library routines abbrev.pl, complete.pl, getopt.pl and
	getopts.pl were assuming $[ == 0.  The Getopt routine wasn't
	returning an error on unrecognized switches.  The look.pl routine
	had never been tested, and didn't work at all.  Now it does.

	There were several difficulties in termcap.pl.  Togoto was documented
	backwards for $rows and $cols.  The Tgetent routine could loop
	endlessly if there was a tc entry.  And it didn't interpret the ^x
	form of specifying control characters right because of base
	treachery (031 instead of 31).  There were also problems with
	using @_ as a temporary array.

	In perl.h, the unused VREG symbol was deleted because it conflicted
	with somebody's header files.

	If perl detects a #! line that specifies some other interpreter
	than perl, it will now start up that interpreter for you.  This
	let's you specify a SHELL of perl to some programs.

	The $/ variable specifies the input record separator.  It was
	possible to set it to a non-text character and read in an entire
	text file as one input, but it wasn't possible to do that
	for a binary file.  Now you can undef $/, and there will be
	no record separator, so you are guaranteed to get the entire
	file with one <>.

	The example in the manual of an open() inside a ?: had the
	branches of the ?: backwards.  I documented the fact that
	grep can modify arrays in place (with caveats about modifying
	literal values).  I also put in how to deal with filenames
	that might have arbitrary characters, and mentioned about the
	problem of unflushed buffers on opens that cause forks.
	It's now documented how to force top of page before the next write.

	Formerly, $0 was guaranteed to contain the name of the perl script
	only till the first regular expression was executed.  It now
	keeps that value permanently.  $0 can no longer be used as a synonym
	for $&.

	The regular expression evaluator didn't handle character classes
	with the 8th bit set.  None of /[\200-\377]/, \d, \w or \s worked
	right--the character class because signed characters were not
	interpreted right, and the builtins because the isdigit(), isalpha()
	and isspace() macros are only defined if isascii() is true.

	Patterns of the form /\bfoo/i didn't work right because the \b
	wants to compare the preceding character with the next one
	to look for word boundaries, and the i modifier forced a move
	of the string to a place where it couldn't do that without
	examining malloc garbage.

	The type glob syntax *foo produces the symbol table entry for
	all the various foo variables.  Perl has to do certain bookkeeping
	when moving such values around.  The symbol table entry was not
	adequately differentiated from normal data to prevent occasion
	confusion, however.

	On MICROPORTs, the CRIPPLED_CC option made the stab_array()
	and stab_hash() macros into function calls, but neglected to
	supply the function definitions.

	The string length allocated to turn a number into a string
	internally turned out to be too short on a Sun 4.

	Several constructs were not recognized properly inside double-quoted
	strings:
		"@foo_bar"	underline in name
		"$foo{}"	required @foo to be defined rather than %foo
		"$foo[$[]"	threw off bracket matcher
		"${1}"		not identified with $1

	The base.term test gives misleading results if /dev/null happens
	not to be a character special file.  So it now checks for that.

	The op.stat could exceed the shell's maximum argument length
	when evaluating </usr/bin/*>.  It now chdirs to /usr/bin and does <*>.

	return grandfathered to never be function call
	The construct
		return (1,2,3);
	did not do what was expected, since return was swallowing the
	parens in order to consider itself a function.  The solution,
	since return never wants any trailing expression such as
		return (1,2,3) + 2;
	is to simply make return an exception to the paren-makes-a-function
	rule, and treat it the way it always was, so that it doesn't
	strip the parens.

	If perldb.pl doesn't exist, there was no reasonable error message
	given when you invoke perl -d.  It now does a do-or-die internally.

	null hereis core dumped
	The hereis construct dumped core on a null string:
		print <<'FOO';
		FOO

	Certain pattern matches weren't working on patterns with embedded
	nulls because the fbminstr() routine, when it decided it couldn't
	do a fancy search, degenerated to using instr(), rather than
	ninstr(), which is better about embedded nulls.

	The s2p sed-to-perl translator didn't translate \< and \> to \b.
	Now it does.

	The a2p awk-to-perl translator didn't put a $ on ExitValue when
	translating the awk exit construct.  It also didn't allow
	logical expressions inside normal expressions:
		i = ($1 == 2 || $2 ~ /bar/)

	a2p.h had definition of a bzero() macro inside an ifdef of BCOPY.
	The two don't always go together, and since Configure is already
	looking for both separately...


Fix:	From rn, say "| patch -p -N -d DIR", where DIR is your perl source
	directory.  Outside of rn, say "cd DIR; patch -p -N <thisarticle".
	If you don't have the patch program, apply the following by hand,
	or get patch (version 2.0, latest patchlevel).

	After patching:
		*** DO NOTHING--INSTALL ALL PATCHES UP THROUGH #12 FIRST ***

	If patch indicates that patchlevel is the wrong version, you may need
	to apply one or more previous patches, or the patch may already
	have been applied.  See the patchlevel.h file to find out what has or
	has not been applied.  In any event, don't continue with the patch.

	If you are missing previous patches they can be obtained from me:

	Larry Wall
	lwall@jpl-devvax.jpl.nasa.gov

	If you send a mail message of the following form it will greatly speed
	processing:

	Subject: Command
	@SH mailpatch PATH perl 3.0 LIST
		   ^ note the c

	where PATH is a return path FROM ME TO YOU either in Internet notation,
	or in bang notation from some well-known host, and LIST is the number
	of one or more patches you need, separated by spaces, commas, and/or
	hyphens.  Saying 35- says everything from 35 to the end.


	You can also get the patches via anonymous FTP from
	jpl-devvax.jpl.nasa.gov (128.149.1.143).

Index: patchlevel.h
Prereq: 8
1c1
< #define PATCHLEVEL 8
---
> #define PATCHLEVEL 9

Index: Configure
Prereq: 3.0.1.4
*** Configure.old	Thu Mar  1 10:33:21 1990
--- Configure	Thu Mar  1 10:48:01 1990
***************
*** 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 3.0.1.4 89/12/21 18:57:00 lwall Locked $
  #
  # Yes, you may rip this off to use in other distribution packages.
  # (Note: this Configure script was generated automatically.  Rather than
--- 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 3.0.1.5 90/02/28 16:17:50 lwall Locked $
  #
  # Yes, you may rip this off to use in other distribution packages.
  # (Note: this Configure script was generated automatically.  Rather than
***************
*** 154,159 ****
--- 154,160 ----
  d_varargs=''
  d_vfork=''
  d_voidsig=''
+ d_volatile=''
  d_vprintf=''
  d_charvspr=''
  d_wait4=''
***************
*** 256,262 ****
  pth="/usr/ucb /bin /usr/bin /usr/local /usr/local/bin /usr/lbin /usr/plx /usr/5bin /vol/local/bin /etc /usr/lib /lib /usr/local/lib /sys5.3/bin /sys5.3/usr/bin /bsd4.3/bin /bsd4.3/usr/bin /bsd4.3/usr/ucb"
  d_newshome="/usr/NeWS"
  defvoidused=7
! libswanted="net_s net nsl_s nsl socket nm ndir ndbm dbm sun bsd x c_s"
  inclwanted='/usr/netinclude /usr/include/sun /usr/include/bsd /usr/include/lan'
  : some greps do not return status, grrr.
  echo "grimblepritz" >grimble
--- 257,263 ----
  pth="/usr/ucb /bin /usr/bin /usr/local /usr/local/bin /usr/lbin /usr/plx /usr/5bin /vol/local/bin /etc /usr/lib /lib /usr/local/lib /sys5.3/bin /sys5.3/usr/bin /bsd4.3/bin /bsd4.3/usr/bin /bsd4.3/usr/ucb"
  d_newshome="/usr/NeWS"
  defvoidused=7
! libswanted="net_s net nsl_s nsl socket nm ndir ndbm dbm sun bsd BSD x c_s PW"
  inclwanted='/usr/netinclude /usr/include/sun /usr/include/bsd /usr/include/lan'
  : some greps do not return status, grrr.
  echo "grimblepritz" >grimble
***************
*** 291,297 ****
      echo "#!/bin/echo hi" > try
      $eunicefix try
      chmod +x try
!     try > today
      if $contains hi today >/dev/null 2>&1; then
  	echo "It does."
  	sharpbang='#!'
--- 292,298 ----
      echo "#!/bin/echo hi" > try
      $eunicefix try
      chmod +x try
!     ./try > today
      if $contains hi today >/dev/null 2>&1; then
  	echo "It does."
  	sharpbang='#!'
***************
*** 299,305 ****
  	echo "#! /bin/echo hi" > try
  	$eunicefix try
  	chmod +x try
! 	try > today
  	if test -s today; then
  	    echo "It does."
  	    sharpbang='#! '
--- 300,306 ----
  	echo "#! /bin/echo hi" > try
  	$eunicefix try
  	chmod +x try
! 	./try > today
  	if test -s today; then
  	    echo "It does."
  	    sharpbang='#! '
***************
*** 332,338 ****
  
  chmod +x try
  $eunicefix try
! if try; then
      echo "Yup, it does."
  else
      echo "Nope.  You may have to fix up the shell scripts to make sure sh runs them."
--- 333,339 ----
  
  chmod +x try
  $eunicefix try
! if ./try; then
      echo "Yup, it does."
  else
      echo "Nope.  You may have to fix up the shell scripts to make sure sh runs them."
***************
*** 1043,1048 ****
--- 1044,1055 ----
      esac
      ;;
  esac
+ if $contains 'LANGUAGE_C' /usr/include/signal.h >/dev/null 2>&1; then
+     case "$dflt" in
+     *LANGUAGE_C*);;
+     *) dflt="$dflt -DLANGUAGE_C";;
+     esac
+ fi
  case "$dflt" in
  '') dflt=none;;
  esac
***************
*** 1208,1214 ****
  }
  EOCP
      if $cc try.c -o try >/dev/null 2>&1 ; then
! 	dflt=`try`
  	case "$dflt" in
  	????|????????) echo "(The test program ran ok.)";;
  	*) echo "(The test program didn't run right for some reason.)";;
--- 1215,1221 ----
  }
  EOCP
      if $cc try.c -o try >/dev/null 2>&1 ; then
! 	dflt=`./try`
  	case "$dflt" in
  	????|????????) echo "(The test program ran ok.)";;
  	*) echo "(The test program didn't run right for some reason.)";;
***************
*** 1422,1428 ****
      fi
  fi
  echo " "
! set $libc $libnames
  $echo $n "Extracting names from $* for later perusal...$c"
  nm $* 2>/dev/null >libc.tmp
  $sed -n -e 's/^.* [AT]  *_[_.]*//p' -e 's/^.* [AT] //p' <libc.tmp >libc.list
--- 1429,1435 ----
      fi
  fi
  echo " "
! set `echo $libc $libnames | tr ' ' '\012' | sort | uniq`
  $echo $n "Extracting names from $* for later perusal...$c"
  nm $* 2>/dev/null >libc.tmp
  $sed -n -e 's/^.* [AT]  *_[_.]*//p' -e 's/^.* [AT] //p' <libc.tmp >libc.list
***************
*** 1435,1440 ****
--- 1442,1449 ----
      $contains '^printf$' libc.list >/dev/null 2>&1 || \
         $sed -n -e 's/^_//' \
  	      -e 's/^\([a-zA-Z_0-9]*\).*xtern.*text.*/\1/p' <libc.tmp >libc.list
+     $contains '^printf$' libc.list >/dev/null 2>&1 || \
+ 	$sed -n -e 's/^.*|FUNC |GLOB .*|//p' <libc.tmp >libc.list
      if $contains '^printf$' libc.list >/dev/null 2>&1; then
  	echo "done"
      else
***************
*** 1605,1611 ****
  
  EOM
  rp="Do you want to do setuid/setgid emulation? [$dflt]"
! echo $n "$rp $c"
  . myread
  case "$ans" in
  '') $ans="$dflt";;
--- 1614,1620 ----
  
  EOM
  rp="Do you want to do setuid/setgid emulation? [$dflt]"
! $echo $n "$rp $c"
  . myread
  case "$ans" in
  '') $ans="$dflt";;
***************
*** 1913,1919 ****
  
  : see if stdio is really std
  echo " "
! if $contains 'char.*_ptr;' /usr/include/stdio.h >/dev/null 2>&1 ; then
      if $contains '_cnt;' /usr/include/stdio.h >/dev/null 2>&1 ; then
  	echo "Your stdio is pretty std."
  	d_stdstdio="$define"
--- 1922,1928 ----
  
  : see if stdio is really std
  echo " "
! if $contains 'char.*_ptr.*;' /usr/include/stdio.h >/dev/null 2>&1 ; then
      if $contains '_cnt;' /usr/include/stdio.h >/dev/null 2>&1 ; then
  	echo "Your stdio is pretty std."
  	d_stdstdio="$define"
***************
*** 2052,2057 ****
--- 2061,2085 ----
  fi
  rm -f $$.tmp
  
+ : check for volatile keyword
+ echo " "
+ echo 'Checking to see if your C compiler knows about "volatile"...'
+ $cat >try.c <<'EOCP'
+ main()
+ {
+ 	volatile int foo;
+ 	foo = foo;
+ }
+ EOCP
+ if $cc -c try.c >/dev/null 2>&1 ; then
+     d_volatile="$define"
+     echo "Yup, it does."
+ else
+     d_volatile="$undef"
+     echo "Nope, it doesn't."
+ fi
+ $rm -f try.*
+ 
  : see if there is a wait4
  set wait4 d_wait4
  eval $inlibc
***************
*** 2216,2222 ****
      echo "No sys/ndir.h found."
  fi
  
! : see if this is DG/UX with a funky utime.h
  echo " "
  if $test -r /usr/include/utime.h ; then
      i_utime="$define"
--- 2244,2250 ----
      echo "No sys/ndir.h found."
  fi
  
! : see if we should include utime.h
  echo " "
  if $test -r /usr/include/utime.h ; then
      i_utime="$define"
***************
*** 2259,2265 ****
  }
  EOCP
      if $cc try.c -o try >/dev/null 2>&1 ; then
! 	dflt=`try`
      else
  	dflt='4'
  	echo "(I can't seem to compile the test program.  Guessing...)"
--- 2287,2293 ----
  }
  EOCP
      if $cc try.c -o try >/dev/null 2>&1 ; then
! 	dflt=`./try`
      else
  	dflt='4'
  	echo "(I can't seem to compile the test program.  Guessing...)"
***************
*** 2317,2323 ****
  }
  EOCP
      if $cc try.c -o try >/dev/null 2>&1 ; then
! 	dflt=`try`
      else
  	dflt='?'
  	echo "(I can't seem to compile the test program...)"
--- 2345,2351 ----
  }
  EOCP
      if $cc try.c -o try >/dev/null 2>&1 ; then
! 	dflt=`./try`
      else
  	dflt='?'
  	echo "(I can't seem to compile the test program...)"
***************
*** 2376,2382 ****
  
  : 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
--- 2404,2410 ----
  
  : 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
***************
*** 2444,2450 ****
  esac
  cont=true
      echo " "
! rp="Which compiler compiler (yacc or bison) will you use? [$dflt]"
  $echo $n "$rp $c"
  . myread
  case "$ans" in
--- 2472,2478 ----
  esac
  cont=true
      echo " "
! rp="Which compiler compiler (yacc or bison -y) will you use? [$dflt]"
  $echo $n "$rp $c"
  . myread
  case "$ans" in
***************
*** 2583,2588 ****
--- 2611,2617 ----
  d_varargs='$d_varargs'
  d_vfork='$d_vfork'
  d_voidsig='$d_voidsig'
+ d_volatile='$d_volatile'
  d_vprintf='$d_vprintf'
  d_charvspr='$d_charvspr'
  d_wait4='$d_wait4'

Index: Makefile.SH
Prereq: 3.0.1.3
*** Makefile.SH.old	Thu Mar  1 10:48:15 1990
--- Makefile.SH	Thu Mar  1 10:48:17 1990
***************
*** 25,33 ****
  
  echo "Extracting Makefile (with variable substitutions)"
  cat >Makefile <<!GROK!THIS!
! # $Header: Makefile.SH,v 3.0.1.3 89/12/21 19:09:26 lwall Locked $
  #
  # $Log:	Makefile.SH,v $
  # Revision 3.0.1.3  89/12/21  19:09:26  lwall
  # patch7: Configure now lets you pick between yacc or bison
  # 
--- 25,36 ----
  
  echo "Extracting Makefile (with variable substitutions)"
  cat >Makefile <<!GROK!THIS!
! # $Header: Makefile.SH,v 3.0.1.4 90/02/28 16:19:43 lwall Locked $
  #
  # $Log:	Makefile.SH,v $
+ # Revision 3.0.1.4  90/02/28  16:19:43  lwall
+ # patch9: extraneous $ on suidperl in Makefile
+ # 
  # Revision 3.0.1.3  89/12/21  19:09:26  lwall
  # patch7: Configure now lets you pick between yacc or bison
  # 
***************
*** 309,315 ****
  	cd x2p; $(MAKE) install
  
  clean:
! 	rm -f *.o all perl taintperl $suidperl perl.man
  	cd x2p; $(MAKE) clean
  
  realclean:
--- 312,318 ----
  	cd x2p; $(MAKE) install
  
  clean:
! 	rm -f *.o all perl taintperl suidperl perl.man
  	cd x2p; $(MAKE) clean
  
  realclean:

Index: x2p/Makefile.SH
Prereq: 3.0.1.3
*** x2p/Makefile.SH.old	Thu Mar  1 10:55:55 1990
--- x2p/Makefile.SH	Thu Mar  1 10:55:57 1990
***************
*** 18,26 ****
  esac
  echo "Extracting x2p/Makefile (with variable substitutions)"
  cat >Makefile <<!GROK!THIS!
! # $Header: Makefile.SH,v 3.0.1.3 89/12/21 20:29:00 lwall Locked $
  #
  # $Log:	Makefile.SH,v $
  # Revision 3.0.1.3  89/12/21  20:29:00  lwall
  # patch7: Configure now lets you pick between yacc or bison
  # 
--- 18,29 ----
  esac
  echo "Extracting x2p/Makefile (with variable substitutions)"
  cat >Makefile <<!GROK!THIS!
! # $Header: Makefile.SH,v 3.0.1.4 90/03/01 10:28:09 lwall Locked $
  #
  # $Log:	Makefile.SH,v $
+ # Revision 3.0.1.4  90/03/01  10:28:09  lwall
+ # patch9: a2p didn't allow logical expressions everywhere it should
+ # 
  # Revision 3.0.1.3  89/12/21  20:29:00  lwall
  # patch7: Configure now lets you pick between yacc or bison
  # 
***************
*** 95,101 ****
  	$(CC) $(LARGE) $(LDFLAGS) $(obj) a2p.o $(libs) -o a2p
  
  a2p.c: a2p.y
! 	@ echo Expect 208 shift/reduce conflicts...
  	$(YACC) a2p.y
  	mv y.tab.c a2p.c
  
--- 98,104 ----
  	$(CC) $(LARGE) $(LDFLAGS) $(obj) a2p.o $(libs) -o a2p
  
  a2p.c: a2p.y
! 	@ echo Expect 232 shift/reduce conflicts...
  	$(YACC) a2p.y
  	mv y.tab.c a2p.c
  

Index: README
*** README.old	Thu Mar  1 10:48:24 1990
--- README	Thu Mar  1 10:48:25 1990
***************
*** 78,85 ****
--- 78,90 ----
      AIX/RT may need a -a switch and -DCRIPPLED_CC.
      SGI machines may need -Ddouble="long float".
      Ultrix (2.3) may need to hand assemble teval.s with a -J switch.
+     Ultrix on MIPS machines may need -DLANGUAGE_C.
      SCO Xenix may need -m25000 for yacc.
      Genix needs to use libc rather than libc_s, or #undef VARARGS.
+     NCR Tower 32 (OS 2.01.01) may need -W2,-Sl,2000 and #undef MKDIR.
+     Machines with half-implemented dbm routines will need to #undef ODBM & NDBM.
+     C's that don't try to restore registers on longjmp() may need -DJMPCLOBBER.
+ 	(Try this if you get random glitches.)
  
  5)  make test
  

Index: eg/README
*** eg/README.old	Thu Mar  1 10:50:26 1990
--- eg/README	Thu Mar  1 10:50:27 1990
***************
*** 1,3 ****
--- 1,7 ----
+ Although supplied with the perl package, the perl scripts in this eg
+ directory and its subdirectories are placed in the public domain, and
+ you may do anything with them that you wish.
+ 
  This stuff is supplied on an as-is basis--little attempt has been made to make
  any of it portable.  It's mostly here to give you an idea of what perl code
  looks like, and what tricks and idioms are used.

Index: x2p/a2p.h
Prereq: 3.0.1.2
*** x2p/a2p.h.old	Thu Mar  1 10:56:02 1990
--- x2p/a2p.h	Thu Mar  1 10:56:04 1990
***************
*** 1,4 ****
! /* $Header: a2p.h,v 3.0.1.2 89/12/21 20:30:29 lwall Locked $
   *
   *    Copyright (c) 1989, Larry Wall
   *
--- 1,4 ----
! /* $Header: a2p.h,v 3.0.1.3 90/03/01 10:29:29 lwall Locked $
   *
   *    Copyright (c) 1989, Larry Wall
   *
***************
*** 6,11 ****
--- 6,14 ----
   *    as specified in the README file that comes with the perl 3.0 kit.
   *
   * $Log:	a2p.h,v $
+  * Revision 3.0.1.3  90/03/01  10:29:29  lwall
+  * patch9: a2p.h had bzero() definition depending on BCOPY
+  * 
   * Revision 3.0.1.2  89/12/21  20:30:29  lwall
   * patch7: arranged so a2p has a chance of running on a 286
   * 
***************
*** 21,28 ****
  #include "../config.h"
  
  #ifndef BCOPY
! #   define bcopy(s1,s2,l) memcpy(s2,s1,l);
! #   define bzero(s,l) memset(s,0,l);
  #endif
  
  #include "handy.h"
--- 24,33 ----
  #include "../config.h"
  
  #ifndef BCOPY
! #   define bcopy(s1,s2,l) memcpy(s2,s1,l)
! #endif
! #ifndef BZERO
! #   define bzero(s,l) memset(s,0,l)
  #endif
  
  #include "handy.h"

Index: x2p/a2p.y
Prereq: 3.0
*** x2p/a2p.y.old	Thu Mar  1 10:56:09 1990
--- x2p/a2p.y	Thu Mar  1 10:56:11 1990
***************
*** 1,5 ****
  %{
! /* $Header: a2p.y,v 3.0 89/10/18 15:34:29 lwall Locked $
   *
   *    Copyright (c) 1989, Larry Wall
   *
--- 1,5 ----
  %{
! /* $Header: a2p.y,v 3.0.1.1 90/03/01 10:30:08 lwall Locked $
   *
   *    Copyright (c) 1989, Larry Wall
   *
***************
*** 7,12 ****
--- 7,15 ----
   *    as specified in the README file that comes with the perl 3.0 kit.
   *
   * $Log:	a2p.y,v $
+  * Revision 3.0.1.1  90/03/01  10:30:08  lwall
+  * patch9: a2p didn't allow logical expressions everywhere it should
+  * 
   * Revision 3.0  89/10/18  15:34:29  lwall
   * 3.0 baseline
   * 
***************
*** 87,114 ****
  		{ $$ = rememberargs($$); }
  	;
  
! patpat	: pat
  		{ $$ = oper1(OPAT,$1); }
! 	| pat ',' pat
  		{ $$ = oper2(ORANGE,$1,$3); }
  	;
  
- pat	: match
- 	| rel
- 	| compound_pat
- 	;
- 
- compound_pat
- 	: '(' compound_pat ')'
- 		{ $$ = oper1(OPPAREN,$2); }
- 	| pat ANDAND maybe pat
- 		{ $$ = oper3(OPANDAND,$1,$3,$4); }
- 	| pat OROR maybe pat
- 		{ $$ = oper3(OPOROR,$1,$3,$4); }
- 	| NOT pat
- 		{ $$ = oper1(OPNOT,$2); }
- 	;
- 
  cond	: expr
  	| match
  	| rel
--- 90,101 ----
  		{ $$ = rememberargs($$); }
  	;
  
! patpat	: cond
  		{ $$ = oper1(OPAT,$1); }
! 	| cond ',' cond
  		{ $$ = oper2(ORANGE,$1,$3); }
  	;
  
  cond	: expr
  	| match
  	| rel
***************
*** 193,199 ****
  		{ $$ = oper1(OUMINUS,$2); }
  	| '+' term %prec UMINUS
  		{ $$ = oper1(OUPLUS,$2); }
! 	| '(' expr ')'
  		{ $$ = oper1(OPAREN,$2); }
  	| GETLINE
  		{ $$ = oper0(OGETLINE); }
--- 180,186 ----
  		{ $$ = oper1(OUMINUS,$2); }
  	| '+' term %prec UMINUS
  		{ $$ = oper1(OUPLUS,$2); }
! 	| '(' cond ')'
  		{ $$ = oper1(OPAREN,$2); }
  	| GETLINE
  		{ $$ = oper0(OGETLINE); }

Index: lib/abbrev.pl
*** lib/abbrev.pl.old	Thu Mar  1 10:51:42 1990
--- lib/abbrev.pl	Thu Mar  1 10:51:43 1990
***************
*** 10,15 ****
--- 10,16 ----
      local(*domain) = @_;
      shift(@_);
      @cmp = @_;
+     local($[) = 0;
      foreach $name (@_) {
  	@extra = split(//,$name);
  	$abbrev = shift(@extra);

Index: arg.h
Prereq: 3.0.1.2
*** arg.h.old	Thu Mar  1 10:48:31 1990
--- arg.h	Thu Mar  1 10:48:34 1990
***************
*** 1,4 ****
! /* $Header: arg.h,v 3.0.1.2 89/12/21 19:13:14 lwall Locked $
   *
   *    Copyright (c) 1989, Larry Wall
   *
--- 1,4 ----
! /* $Header: arg.h,v 3.0.1.3 90/02/28 16:21:55 lwall Locked $
   *
   *    Copyright (c) 1989, Larry Wall
   *
***************
*** 6,11 ****
--- 6,14 ----
   *    as specified in the README file that comes with the perl 3.0 kit.
   *
   * $Log:	arg.h,v $
+  * Revision 3.0.1.3  90/02/28  16:21:55  lwall
+  * patch9: added pipe function
+  * 
   * Revision 3.0.1.2  89/12/21  19:13:14  lwall
   * patch7: send() didn't allow a TO argument
   * 
***************
*** 211,217 ****
  #define O_LAELEM 191
  #define O_LHELEM 192
  #define O_LOCAL 193
! #define O_UNUSED 194
  #define O_FILENO 195
  #define O_GHBYNAME 196
  #define O_GHBYADDR 197
--- 214,220 ----
  #define O_LAELEM 191
  #define O_LHELEM 192
  #define O_LOCAL 193
! #define O_PIPE 194
  #define O_FILENO 195
  #define O_GHBYNAME 196
  #define O_GHBYADDR 197
***************
*** 458,464 ****
      "LAELEM",
      "LHELEM",
      "LOCAL",
!     "UNUSED",
      "FILENO",
      "GHBYNAME",
      "GHBYADDR",
--- 461,467 ----
      "LAELEM",
      "LHELEM",
      "LOCAL",
!     "PIPE",
      "FILENO",
      "GHBYNAME",
      "GHBYADDR",
***************
*** 832,838 ****
  	A(0,1,0),	/* LAELEM */
  	A(0,1,0),	/* LHELEM */
  	A(1,0,0),	/* LOCAL */
! 	A(0,0,0),	/* UNUSED */
  	A(1,0,0),	/* FILENO */
  	A(1,0,0),	/* GHBYNAME */
  	A(1,1,0),	/* GHBYADDR */
--- 835,841 ----
  	A(0,1,0),	/* LAELEM */
  	A(0,1,0),	/* LHELEM */
  	A(1,0,0),	/* LOCAL */
! 	A(0,0,0),	/* PIPE */
  	A(1,0,0),	/* FILENO */
  	A(1,0,0),	/* GHBYNAME */
  	A(1,1,0),	/* GHBYADDR */

*** End of Patch 9 ***

clewis@eci386.uucp (Chris Lewis) (03/07/90)

In article <7238@jpl-devvax.JPL.NASA.GOV> lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) writes:
> System: perl version 3.0
> Patch #: 9
> Priority: HIGH

> Subject: libBSD.a and libPW.a are now supported

I'm not sure what libBSD.a is supposed to contain, but I think it's
a big mistake to include libPW.a by default...  

libPW.a (I seem to recall) is a set of routines for continued
support of code that used PWB Unix libraries way back in the
stone age (how old does it make me? ;-) and/or "accidentally"
matched the names and functionality of more recent BSD functionality. 
Eg: alloca(), rename() etc.  As far as I can tell, libPW functions are 
not specifically documented in *any* current SV documentation and are 
not supported by many system vendors (in fact, some of the more grungy ones
often don't work on different platforms - like alloca).  rename() for
example, isn't documented in SVID (vol 1..3) nor the appropriate
Programmer's Reference for our system (SVR3).

Gawd only knows what some of the other routines in libPW.a do...

I built PL12 on 386/ix, and had the fatal() clash as mentioned elsewhere.
I then editted Makefile (to shorten rebuild time) and the link complained
about "rename()" not found.  So, I rebuilt from scratch after omitting
-lPW (at the Configure prompt), and all worked fine.  (well... haven't
tested it yet - later ;-)

Thus, in my case, the only function found in libPW.a that was of use
to Perl was rename().  Our kernel doesn't support a "rename" system call,
and rename would have to do link()/unlink()/link() anyways (which Perl
already supports if RENAME undef'd).  So, at least in my case, looking 
in libPW.a was really a waste of time.

Are there any other functions that perl's using from other people's libPW.a?
-- 
Chris Lewis, Elegant Communications Inc, {uunet!attcan,utzoo}!lsuc!eci386!clewis
Ferret mailing list: eci386!ferret-list, psroff mailing list: eci386!psroff-list

lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) (03/08/90)

In article <1990Mar6.223913.8337@eci386.uucp> clewis@eci386.UUCP (Chris Lewis) writes:
: Are there any other functions that perl's using from other people's libPW.a?

Pretty much the only function that people might want from -lPW is
alloca(), and then only if they bison and don't otherwise have alloca().
I'll remove it from the default.

Larry