Subject: sprintf() returning 'int' breaks f77 (#247)
Index:	usr.bin/f77/driver.c,pdp11.c 2.11BSD

Description:
	Update #233 changed the return value of sprintf() from
	"char *" (a copy of the first parameter) to 'int' (the
	number of characters placed in the buffer).

	This change breaks applications which relied on the 
	return value of sprintf() being a buffer address.

	f77 is one of those applications.

Repeat-By:
	Compile a Fortran program.  Since a 'int' is being passed instead
	of a string in a number of places the result is either a stream of
	errors or a core dump.

Fix:
	Thanks to Tom (tih@nhh.no) for spotting this and providing the
	initial fix.  

	The 'Makefile' was updated slightly to take advantage of the ability
	to pipe into the assembler ('as').  This speeds things up somewhat
	by removing a 'mv' and creation of another intermediate file.

	Apply the patch below, recompile and install f77:

	1) Cut where indicated and save to a file, /tmp/247
	2) patch -p0 < /tmp/247
	3) cd /usr/src/usr.bin/f77
	4) make
	   make install
	   make clean

===========================cut here==========================
*** /usr/src/usr.bin/f77/Makefile.old	Mon Jan 18 09:36:47 1993
--- /usr/src/usr.bin/f77/Makefile	Fri Jun  9 21:33:01 1995
***************
*** 2,8 ****
  #	generating code for the PDP11,
  #	using the Ritchie pass 2
  #
! #	3/8/85  WEB
  #
  
  AS=		as -V
--- 2,8 ----
  #	generating code for the PDP11,
  #	using the Ritchie pass 2
  #
! #	1995/06/09 - 2.11BSD
  #
  
  AS=		as -V
***************
*** 73,86 ****
  #	Remove error strings
  		mkstr - f77_strings xx $*.c
  		${CC} -S ${CFLAGS} xx$*.c
- 		mv xx$*.s $*.s
  #	Move switch code to text space
! 		-if [ X${SEPFLAG} = X-n ]; then ed - $*.s < :rofix; fi
! 		rm xx$*.c
! 		${C2} $*.s x.s
! 		mv x.s $*.s
! 		${AS} - -o $*.o $*.s
! 		rm $*.s
  
  driver.o:
  pdp11x.o:
--- 73,82 ----
  #	Remove error strings
  		mkstr - f77_strings xx $*.c
  		${CC} -S ${CFLAGS} xx$*.c
  #	Move switch code to text space
! 		-if [ X${SEPFLAG} = X-n ]; then ed - xx$*.s < :rofix; fi
! 		${C2} xx$*.s | ${AS} -u -o $*.o
! 		rm xx$*.c xx$*.s
  
  driver.o:
  pdp11x.o:
*** /usr/src/usr.bin/f77/driver.c.old	Sun Jun 12 16:24:58 1988
--- /usr/src/usr.bin/f77/driver.c	Fri Jun  9 21:07:06 1995
***************
*** 1,4 ****
! char *xxxvers[] = "\n FORTRAN 77 DRIVER, VERSION 1.13+,   24 SEP 1982\n";
  
  #include <stdio.h>
  #include <ctype.h>
--- 1,4 ----
! char *xxxvers[] = "\n FORTRAN 77 DRIVER, VERSION 1.13.1+,   09 JUN 1995\n";
  
  #include <stdio.h>
  #include <ctype.h>
***************
*** 268,274 ****
  
  			if(macroflag)
  				{
! 				if(sys(sprintf(buff, "%s %s >%s", macroname, infname, prepfname) ))
  					{
  					rmf(prepfname);
  					erred = YES;
--- 268,275 ----
  
  			if(macroflag)
  				{
! 				sprintf(buff, "%s %s >%s", macroname, infname, prepfname);
! 				if (sys(buff))
  					{
  					rmf(prepfname);
  					erred = YES;
***************
*** 442,451 ****
  #ifdef PASS2OPT
  if(optimflag)
  	{
! 	if( sys(sprintf(buff, "%s %s %s", PASS2OPT, asmpass2, optzfname)) )
  		rmf(optzfname);
  	else
! 		sys(sprintf(buff,"mv %s %s", optzfname, asmpass2));
  	}
  #endif
  #endif
--- 443,456 ----
  #ifdef PASS2OPT
  if(optimflag)
  	{
! 	sprintf(buff, "%s %s %s", PASS2OPT, asmpass2, optzfname);
! 	if (sys(buff))
  		rmf(optzfname);
  	else
! 		{
! 		sprintf(buff,"mv %s %s", optzfname, asmpass2);
! 		sys(buff);
! 		}
  	}
  #endif
  #endif
***************
*** 454,464 ****
  	{
  	*lastc = 's';
  #if TARGET == INTERDATA
! 	sys( sprintf(buff, "cat %s %s %s >%s",
! 		asmfname, setfname, asmpass2, obj) );
  #else
! 	sys( sprintf(buff, "cat %s %s >%s",
! 			asmfname, asmpass2, obj) );
  #endif
  	*lastc = 'o';
  	}
--- 459,469 ----
  	{
  	*lastc = 's';
  #if TARGET == INTERDATA
! 	sprintf(buff, "cat %s %s %s >%s", asmfname, setfname, asmpass2, obj);
! 	sys(buff);
  #else
! 	sprintf(buff, "cat %s %s >%s", asmfname, asmpass2, obj);
! 	sys(buff);
  #endif
  	*lastc = 'o';
  	}
***************
*** 472,478 ****
  
  #if TARGET == VAX
  	/* vax assembler currently accepts only one input file */
! 	sys(sprintf(buff, "cat %s >>%s", asmpass2, asmfname));
  	sprintf(buff, "%s -o %s %s", asmname, obj, asmfname);
  #endif
  
--- 477,484 ----
  
  #if TARGET == VAX
  	/* vax assembler currently accepts only one input file */
! 	sprintf(buff, "cat %s >>%s", asmpass2, asmfname);
! 	sys(buff);
  	sprintf(buff, "%s -o %s %s", asmname, obj, asmfname);
  #endif
  
***************
*** 536,544 ****
  #if HERE==INTERDATA
  	if(optimflag)
  		{
! 		char buff[100];
! 		if( sys(sprintf(buff, "nopt %s -o junk.%d", aoutname, pid))
! 		 || sys(sprintf(buff, "mv junk.%d %s", pid, aoutname)) )
  			err("bad optimization");
  		}
  #endif
--- 542,551 ----
  #if HERE==INTERDATA
  	if(optimflag)
  		{
! 		char bufa[100], bufb[100];
! 		sprintf(bufa, "nopt %s -o junk.%d", aoutname, pid);
! 		sprintf(bufb, "mv junk.%d %s", pid, aoutname);
! 		if (sys(bufa) || sys(bufb))
  			err("bad optimization");
  		}
  #endif
***************
*** 961,967 ****
  char *t, *d;
  {
  char buff[100];
! fatal( sprintf(buff, t, d) );
  }
  
  
--- 968,975 ----
  char *t, *d;
  {
  char buff[100];
! sprintf(buff, t, d);
! fatal(buff);
  }
  
  
***************
*** 1006,1012 ****
  totlen = 0;
  nch = 0;
  
! if(status = sys( sprintf(buff, "sort %s >%s", initfname, sortfname) ) )
  	fatal1("call sort status = %d", status);
  if( (sortfile = fopen(sortfname, "r")) == NULL)
  	badfile(sortfname);
--- 1014,1021 ----
  totlen = 0;
  nch = 0;
  
! sprintf(buff, "sort %s >%s", initfname, sortfname);
! if (status = sys(buff))
  	fatal1("call sort status = %d", status);
  if( (sortfile = fopen(sortfname, "r")) == NULL)
  	badfile(sortfname);
*** /usr/src/usr.bin/f77/pdp11.c.old	Sun Jun 12 16:24:58 1988
--- /usr/src/usr.bin/f77/pdp11.c	Fri Jun  9 20:34:02 1995
***************
*** 1,3 ****
--- 1,8 ----
+ /*
+  * 1995/06/09.  sprintf() returns an int (since patch #233) rather
+  * 	   a "char *".  
+ */
+ 
  #include "defs"
  #include "string_defs"
  #if FAMILY == DMR
***************
*** 29,35 ****
  	p2op(P2RETURN);
  #endif
  #if FAMILY==SCJ
! 	p2pass(sprintf(textline, "\tjmp\tcret"));
  #endif
  }
  
--- 34,41 ----
  	p2op(P2RETURN);
  #endif
  #if FAMILY==SCJ
! 	sprintf(textline, "\tjmp\tcret");
! 	p2pass(textline);
  #endif
  }
  
***************
*** 70,76 ****
  	putstmt();
  #endif
  #if FAMILY == SCJ
! 	p2pass(sprintf(textline, "\tmov\t%d.(r5),%d.(r4)", m, n));
  #endif
  }
  
--- 76,83 ----
  	putstmt();
  #endif
  #if FAMILY == SCJ
! 	sprintf(textline, "\tmov\t%d.(r5),%d.(r4)", m, n);
! 	p2pass(textline);
  #endif
  }
  
***************
*** 154,169 ****
  if(p->vtype == TYLONG)
  	{
  	regno = 1;
! 	p2pass(sprintf(textline, "\ttst\tr0"));
! 	p2pass(sprintf(textline, "\tbne\tL%d", skiplabel));
  	}
  else
  	regno = 0;
  
! p2pass(sprintf(textline, "\tcmp\tr%d,$%d.", regno, nlab));
! p2pass(sprintf(textline, "\tbhi\tL%d", skiplabel));
! p2pass(sprintf(textline, "\tasl\tr%d", regno));
! p2pass(sprintf(textline, "\tjmp\t*L%d(r%d)", labarray, regno));
  }
  
  
--- 161,182 ----
  if(p->vtype == TYLONG)
  	{
  	regno = 1;
! 	sprintf(textline, "\ttst\tr0");
! 	p2pass(textline);
! 	sprintf(textline, "\tbne\tL%d", skiplabel);
! 	p2pass(textline);
  	}
  else
  	regno = 0;
  
! sprintf(textline, "\tcmp\tr%d,$%d.", regno, nlab);
! p2pass(textline);
! sprintf(textline, "\tbhi\tL%d", skiplabel);
! p2pass(textline);
! sprintf(textline, "\tasl\tr%d", regno);
! p2pass(textline);
! sprintf(textline, "\tjmp\t*L%d(r%d)", labarray, regno);
! p2pass(textline);
  }
  
  
***************
*** 176,198 ****
  putforce( ptype = p->vtype, p);
  if( ISINT(ptype) )
  	{
! 	p2pass(sprintf(textline, "\ttst\tr0"));
! 	p2pass(sprintf(textline, "\tjlt\tL%d", neg));
! 	p2pass(sprintf(textline, "\tjgt\tL%d", pos));
  	if(ptype != TYSHORT)
  		{
! 		p2pass(sprintf(textline, "\ttst\tr1"));
! 		p2pass(sprintf(textline, "\tjeq\tL%d", zer));
  		}
! 	p2pass(sprintf(textline, "\tjbr\tL%d", pos));
  	}
  else
  	{
! 	p2pass(sprintf(textline, "\ttstf\tr0"));
! 	p2pass(sprintf(textline, "\tcfcc"));
! 	p2pass(sprintf(textline, "\tjeq\tL%d", zer));
! 	p2pass(sprintf(textline, "\tjlt\tL%d", neg));
! 	p2pass(sprintf(textline, "\tjmp\tL%d", pos));
  	}
  }
  
--- 189,222 ----
  putforce( ptype = p->vtype, p);
  if( ISINT(ptype) )
  	{
! 	sprintf(textline, "\ttst\tr0");
! 	p2pass(textline);
! 	sprintf(textline, "\tjlt\tL%d", neg);
! 	p2pass(textline);
! 	sprintf(textline, "\tjgt\tL%d", pos);
! 	p2pass(textline);
  	if(ptype != TYSHORT)
  		{
! 		sprintf(textline, "\ttst\tr1");
! 		p2pass(textline);
! 		sprintf(textline, "\tjeq\tL%d", zer);
! 		p2pass(textline);
  		}
! 	sprintf(textline, "\tjbr\tL%d", pos);
! 	p2pass(textline);
  	}
  else
  	{
! 	sprintf(textline, "\ttstf\tr0");
! 	p2pass(textline);
! 	sprintf(textline, "\tcfcc");
! 	p2pass(textline);
! 	sprintf(textline, "\tjeq\tL%d", zer);
! 	p2pass(textline);
! 	sprintf(textline, "\tjlt\tL%d", neg);
! 	p2pass(textline);
! 	sprintf(textline, "\tjmp\tL%d", pos);
! 	p2pass(textline);
  	}
  }
  
***************
*** 265,271 ****
  prtail()
  {
  #if FAMILY == SCJ
! 	p2pass(sprintf(textline, "\t.globl\tcsv,cret"));
  #else
  	p2op(P2EOF);
  #endif
--- 289,296 ----
  prtail()
  {
  #if FAMILY == SCJ
! 	sprintf(textline, "\t.globl\tcsv,cret");
! 	p2pass(textline);
  #else
  	p2op(P2EOF);
  #endif
***************
*** 299,312 ****
  if(profileflag)
  	proflab = newlabel();
  #if FAMILY == SCJ
! 	p2pass(sprintf(textline, "\tjsr\tr5,csv"));
  	if(profileflag)
  		{
  		fprintf(asmfile, ".data\nL%d:\t_%s+1\n.bss\n", proflab, funcname);
! 		p2pass(sprintf(textline, "\tmov\t$L%d,r0", proflab));
! 		p2pass(sprintf(textline, "\tjsr\tpc,mcount"));
  		}
! 	p2pass(sprintf(textline, "\tsub\t$.F%d,sp", procno));
  #else
  	p2op(P2SAVE);
  	if(profileflag) {
--- 324,341 ----
  if(profileflag)
  	proflab = newlabel();
  #if FAMILY == SCJ
! 	sprintf(textline, "\tjsr\tr5,csv");
! 	p2pass(textline);
  	if(profileflag)
  		{
  		fprintf(asmfile, ".data\nL%d:\t_%s+1\n.bss\n", proflab, funcname);
! 		sprintf(textline, "\tmov\t$L%d,r0", proflab);
! 		p2pass(textline);
! 		sprintf(textline, "\tjsr\tpc,mcount");
! 		p2pass(textline);
  		}
! 	sprintf(textline, "\tsub\t$.F%d,sp", procno);
! 	p2pass(textline);
  #else
  	p2op(P2SAVE);
  	if(profileflag) {
***************
*** 376,382 ****
  char *s;
  {
  #if FAMILY == SCJ
! 	p2pass(sprintf(textline, "_%s:", s));
  #else
  	p2op(P2RLABEL);
  	putc('_', textfile);
--- 405,412 ----
  char *s;
  {
  #if FAMILY == SCJ
! 	sprintf(textline, "_%s:", s);
! 	p2pass(textline);
  #else
  	p2op(P2RLABEL);
  	putc('_', textfile);
***************
*** 391,398 ****
  int k;
  {
  #if FAMILY == SCJ
! 	p2pass(sprintf(textline, "\tmov\tr5,r4"));
! 	p2pass(sprintf(textline, "\tadd\t$%d.,r4", k));
  #else
  	p2reg(ARGREG, P2SHORT);
  	p2reg(AUTOREG, P2SHORT);
--- 421,430 ----
  int k;
  {
  #if FAMILY == SCJ
! 	sprintf(textline, "\tmov\tr5,r4");
! 	p2pass(textline);
! 	sprintf(textline, "\tadd\t$%d.,r4", k);
! 	p2pass(textline);
  #else
  	p2reg(ARGREG, P2SHORT);
  	p2reg(AUTOREG, P2SHORT);
***************
*** 449,457 ****
  for(hp = hashtab ; hp<lasthash ; ++hp)
      if(p = hp->varp)
  	{
! 	s = NULL;
  	if(p->vstg == STGARG)
! 		s = sprintf(buff, "%o", p->vardesc.varno+argloc);
  	else if(p->vclass == CLVAR)
  		switch(p->vstg)
  			{
--- 481,489 ----
  for(hp = hashtab ; hp<lasthash ; ++hp)
      if(p = hp->varp)
  	{
! 	buff[0] = '\0';
  	if(p->vstg == STGARG)
! 		sprintf(buff, "%o", p->vardesc.varno+argloc);
  	else if(p->vclass == CLVAR)
  		switch(p->vstg)
  			{
***************
*** 460,479 ****
  			case STGEQUIV:
  				t = memname(p->vstg, p->vardesc.varno);
  				if(p->voffset)
! 					s = sprintf(buff, "%s+%o", t, p->voffset);
  				else
! 					s = sprintf(buff, "%s", t);
  				break;
  
  			case STGAUTO:
! 				s = sprintf(buff, "%o", p->voffset);
  				break;
  
  			default:
  				break;
  			}
! 	if(s)
! 		fprintf(asmfile, "~%s = %s\n", varstr(VL,p->varname), s);
  	}
  fprintf(asmfile, "~~:\n");
  }
--- 492,511 ----
  			case STGEQUIV:
  				t = memname(p->vstg, p->vardesc.varno);
  				if(p->voffset)
! 					sprintf(buff, "%s+%o", t, p->voffset);
  				else
! 					sprintf(buff, "%s", t);
  				break;
  
  			case STGAUTO:
! 				sprintf(buff, "%o", p->voffset);
  				break;
  
  			default:
  				break;
  			}
! 	if (buff[0])
! 		fprintf(asmfile, "~%s = %s\n", varstr(VL,p->varname), buff);
  	}
  fprintf(asmfile, "~~:\n");
  }
*** /VERSION.old	Sat May 20 21:04:31 1995
--- /VERSION	Fri Jun  9 20:57:38 1995
***************
*** 1,4 ****
! Current Patch Level: 246
  
  2.11 BSD
  ============
--- 1,4 ----
! Current Patch Level: 247
  
  2.11 BSD
  ============
