Subject: 'as' does not properly read stdin (#183)
Index:	bin/as1.s, man/man1/as.1 2.11BSD

Description:
	'as' does not read 'stdin' if there are no files specified.

Repeat-By:
	/lib/cpp -E foo.c | sed -e ';^#;/;' | as -o foo.o

Fix:
	The support added for reading 'stdin' was incomplete.  The
	special file '-' would be recognized but only between regular
	files:

		as -o foo.o foo.s - bar.s

	would work but:

		as -o foo.o -

	would not.

	The reason is that the '-' is an old synonym for '-u' which means
	to treat undeclared symbols as global undefined symbols.  This use
	is deprecated (the compiler no longer uses it) and may go away in
	the future.

	The fix to allow 'as' to read stdin anywhere is to use '--' as
	the special name for 'stdin'.  

	Also, the list of file arguments is now optional.  If there are
	no input files given to 'as' then "stdin" is read automatically.

	The valid 'as' commands now include:

		as -o foo.o 
		(read stdin and write foo.o)

		as -o foo.o --
		(read stdin and write foo.o)

		as -o foo.o foo.s -- bar.s
		(read foo.s, then read stdin, then read bar.s)

		as -o foo.o foo.s - bar.s
		(same as above)

	The ability of 'as' to read "stdin" is very useful in several of
	the system Makefiles, notably the libc/pdp directories.  Instead
	of creating a /tmp file from the output of 'cpp' or 'sed' it is
	possible to pipe directly into 'as'.  The time savings are quite
	noticeable - at least 10% when doing the files in libc/pdp/sys.

	The following patch updates the assembler and the man page.

	1) Save the following to a file (/tmp/p)
	2) patch -p0 < /tmp/p
	3) cd /usr/src/bin/as; make; make install; make clean
	4) cd /usr/src/man/man1; /usr/man/manroff as.1 > /usr/man/cat1/as.0
	5) rm /tmp/p

	Previous updates and fixes are available via anonymous FTP to
	'ftp.iipo.gtegsc.com' in the directory /pub/2.11BSD.

=========cut here
*** /usr/src/bin/as/as0.s.old	Sat Feb  5 19:57:41 1994
--- /usr/src/bin/as/as0.s	Fri Mar 11 22:37:37 1994
***************
*** 78,101 ****
  	add	$2,curarg		/ argv++
  1:
  	mov	*curarg,r1
! 	cmpb	(r1),$'-
  	bne	1f
  	add	$2,curarg		/ argv++
  	dec	r0			/ argc--
! 	cmpb	1(r1),$'u
  	beq	3f
! 	cmpb	1(r1), $'V
  	bne	2f
  	inc	overlaid
  	br	1b
  2:
! 	tstb	1(r1)
  	bne	2f
  3:
  	mov	$40,defund
  	br	1b
  2:
! 	cmpb	1(r1),$'o
  	bne	1f
  	mov	*curarg,a.outp
  	br	9b
--- 78,106 ----
  	add	$2,curarg		/ argv++
  1:
  	mov	*curarg,r1
! 	cmpb	(r1)+,$'-
  	bne	1f
+ 	cmpb	(r1),$'-		/ is this "--"?
+ 	bne	8f			/ no - br
+ 	tstb	1(r1)			/ check for null terminator
+ 	beq	1f			/ got it, the "--" means read 'stdin'
+ 8:
  	add	$2,curarg		/ argv++
  	dec	r0			/ argc--
! 	cmpb	(r1),$'u
  	beq	3f
! 	cmpb	(r1), $'V
  	bne	2f
  	inc	overlaid
  	br	1b
  2:
! 	tstb	(r1)
  	bne	2f
  3:
  	mov	$40,defund
  	br	1b
  2:
! 	cmpb	(r1),$'o
  	bne	1f
  	mov	*curarg,a.outp
  	br	9b
***************
*** 110,115 ****
--- 115,124 ----
  	movb	$32.,Ncps
  1:
  	mov	r0,nargs		/ # of remaining args
+ 	bne	8f			/ br if any left
+ 	inc	nargs			/ fake at least one arg
+ 	mov	$dash, curarg		/ of '-' so we read stdin
+ 8:
  	mov	$a.tmp1,-(sp)
  	jsr	pc,_mkstemp		/ fout = mkstemp(a.tmp1);
  	tst	(sp)+
***************
*** 753,759 ****
  	jsr	pc,error
  	jmp	aexit
  2:
! / check for the filename argument of "-", this means to read 'stdin'.
  / Additional filenames are permitted and will be processed when EOF
  / is detected on stdin.
  	mov	*curarg,r0
--- 762,768 ----
  	jsr	pc,error
  	jmp	aexit
  2:
! / check for the filename arguments of "-" or "--", these mean to read 'stdin'.
  / Additional filenames are permitted and will be processed when EOF
  / is detected on stdin.
  	mov	*curarg,r0
***************
*** 760,766 ****
  	cmpb	(r0)+,$'-
  	bne	5f			/ not the special case - br
  	tstb	(r0)			/ must be '-' by itself
! 	bne	5f
  	clr	fin			/ file descriptor is 0 for stdin
  	br	2f
  5:
--- 769,780 ----
  	cmpb	(r0)+,$'-
  	bne	5f			/ not the special case - br
  	tstb	(r0)			/ must be '-' by itself
! 	beq	4f
! 	cmpb	(r0)+,$'-		/ check for "--"
! 	bne	5f			/ not a double -, must be a filename
! 	tstb	(r0)			/ null terminated?
! 	bne	5f			/ no - must be a filename
! 4:
  	clr	fin			/ file descriptor is 0 for stdin
  	br	2f
  5:
***************
*** 1506,1512 ****
--- 1520,1528 ----
  
  a.tmp1:	</tmp/atm1XX\0>
  Ncps:	.byte 8.
+ 1:	<-\0>
  	.even
+ dash:	1b
  fin:	-1
  fout:	-1
  / The next two _must_ be adjacent!  Not sure why, but then this whole
*** /usr/src/man/man1/as.1.old	Thu Feb 12 06:36:43 1987
--- /usr/src/man/man1/as.1	Fri Mar 11 22:47:27 1994
***************
*** 5,23 ****
  .SH SYNOPSIS
  .B as
  [
! .B \-
  ] [
  .B \-V
  ] [
  .B \-o
  objfile
! ] file ...
  .SH DESCRIPTION
  .I As
  assembles the concatenation of the named files.
  The options are:
  .TP
! .B \-
  Treat all undefined symbols in the assembly as external globals.
  .TP
  .B \-\^V
--- 5,23 ----
  .SH SYNOPSIS
  .B as
  [
! .B \-u
  ] [
  .B \-V
  ] [
  .B \-o
  objfile
! ] file ... 
  .SH DESCRIPTION
  .I As
  assembles the concatenation of the named files.
  The options are:
  .TP
! .B \-u
  Treat all undefined symbols in the assembly as external globals.
  .TP
  .B \-\^V
***************
*** 31,41 ****
  .I a.out
  is used.  If no errors occurred during the assembly and if
  there were no unresolved external references, it is made executable.
! .SH FILES
! .ta 2i
! /lib/as2	pass 2 of the assembler
  .br
! /tmp/atm[1-3]?	temporary
  .br
  a.out	object
  .SH "SEE ALSO"
--- 31,60 ----
  .I a.out
  is used.  If no errors occurred during the assembly and if
  there were no unresolved external references, it is made executable.
! .P
! The special file name
! .B \-\-
! serves two purposes.  It signals the end of all options and causes
! .I stdin
! to be read for input.  Thus it is now possible to pipe data to the
! assembler:
  .br
! .sp
! /lib/cpp -E foo.s | sed -e ';^#;/;' | as -o foo.o --
! .br
! .sp
! The file name
! .B \-\-
! may be placed between normal files, when EOF is detected on 
! .I stdin
! the next file in the argument list is opened and read.
! .br
! .sp
! If no input files are specified then 
! .I stdin
! is read.
! .SH FILES
! /tmp/atm1	temporary
  .br
  a.out	object
  .SH "SEE ALSO"
