[comp.lang.c++] form

jr@uplherc.UUCP (J.R. Westmoreland) (07/17/87)

The form function can not handle a very large or complex format.  The
reason is that the call to sprintf in the file out.c onlly copies
10*sizeof(int) bytes of the argument list.
The following small test program will exhibit the bug.

#include <stream.h>
main()
{
    float x1 = 1.5, x2 = 2.5, x3 = 3.5, x4 = 4.5, x5 = 5.5,
	x6 = 6.5, x7 = 7.5, x8 = 8.5, x9 = 9.5, x10 = 10.5;

    cout << form("float\t%g %g %g %g %g %g %g %g %g %g\n", x1, x2, x3, x4, x5,
	x6, x7, x8, x9, x10);
}

Here is the patch that overcomes the problem.  I have tested the patch for BSD
but do not have a easy way to test the sysv patch.  I believe that
this patch will also work on v1.2 but since we do not have that version yet I
am not positive.

*** /usr/c++/incl/stdio.h.orig	Fri Jul 17 08:59:43 1987
--- /usr/c++/incl/stdio.h	Fri Jul 17 09:08:23 1987
***************
*** 30,37 ****
--- 30,43 ----
  #define	_IOMYBUF  0010
  #define	_IOEOF    0020
  #define	_IOERR    0040
+ #ifdef BSD
+ #define _IOSTRG   0100
+ #define	_IOLBF    0200
+ #define	_IORW     0400
+ #else
  #define	_IOLBF    0100
  #define	_IORW     0200
+ #endif
  #define	NULL 0
  #define	FILE struct _iobuf
  #define	EOF (-1)
*** /usr/c++/lib/stream/out.c.orig	Fri Dec 19 11:01:05 1986
--- /usr/c++/lib/stream/out.c	Fri Jul 17 09:24:45 1987
***************
*** 8,13 ****
--- 8,19 ----
  strlen(const char*);
  #include "stream.h"
  #include <common.h>
+ # ifdef BSD
+ #include <stdio.h>
+ _doprnt(const char*, int*, FILE*);
+ #else
+ vsprintf(char*, char*, int*);
+ #endif
  
  
  #define MAXOSTREAMS 20
***************
*** 70,76 ****
  	register char* buf = bfree;
  	if (max < buf+fld_size) buf = formbuf;
  
! 	register ll = sprintf(buf,format,ap[0],ap[1],ap[2],ap[3],ap[4],ap[5],ap[6],ap[7],ap[8],ap[9]);	// too few words copied
  	if (0<ll && ll<cb_size)				// length
  		;
  	else if (buf<(char*)ll && (char*)ll<buf+cb_size)// pointer to trailing 0
--- 76,93 ----
  	register char* buf = bfree;
  	if (max < buf+fld_size) buf = formbuf;
  
! # ifdef BSD
! 	register ll;
! 	FILE _strbuf;
! 	_strbuf._flag = _IOWRT+_IOSTRG;
! 	_strbuf._base = _strbuf._ptr = buf;
! 	_strbuf._cnt = 32767;
! 	_doprnt(format, ap, &_strbuf);
! 	putc('\0', &_strbuf);
! 	ll = strlen(buf);
! # else
! 	register ll = vsprintf(buf, format, ap);
! #endif
  	if (0<ll && ll<cb_size)				// length
  		;
  	else if (buf<(char*)ll && (char*)ll<buf+cb_size)// pointer to trailing 0


J. R. Westmoreland
Utah Power & Light Company
+1 801 535-4784

mcdougal@cs.uchicago.edu (05/05/91)

The form function in C++, i.e.:

   cout << form(<control-string>,<args>) ;

seems to be broken.  Let p be a pointer to a vector of floats.

   cout << p[1];    // this works

   cout << form("%f",p[1]) ;   // IOT Trap (Core dumped)

Supposedly we have the latest compiler from AT&T.  Is this a know problem?

-Tom

russb@alexa.JPL.NASA.GOV (Russ Brill) (05/11/91)

>The form function in C++, i.e.:
>
>   cout << form(<control-string>,<args>) ;
>
>seems to be broken.  Let p be a pointer to a vector of floats.
>
>  cout << p[1];    // this works
>
>   cout << form("%f",p[1]) ;   // IOT Trap (Core dumped)
>

We've also had problems with form().  Specifically, something like

	form("%-20.10s","abc")

compiles just fine, but it generates 20 blanks.  This is on Sun's
cfront 2.0 on a Sparc (works just fine on our Sun 3's).

kgorlen@alw.nih.gov (Keith Gorlen) (05/11/91)

In article <1991May10.200911.28671@jpl-devvax.jpl.nasa.gov>, russb@alexa.JPL.NASA.GOV (Russ Brill) writes:
|> >The form function in C++, i.e.:
|> >
|> >   cout << form(<control-string>,<args>) ;
|> >
|> >seems to be broken.  Let p be a pointer to a vector of floats.
|> >
|> >  cout << p[1];    // this works
|> >
|> >   cout << form("%f",p[1]) ;   // IOT Trap (Core dumped)
|> >
|> 
|> We've also had problems with form().  Specifically, something like
|> 
|> 	form("%-20.10s","abc")
|> 
|> compiles just fine, but it generates 20 blanks.  This is on Sun's
|> cfront 2.0 on a Sparc (works just fine on our Sun 3's).

Try compiling the iostream libraries with -DVSPRINTF=vsprintf.  form()
uses non-portable code that doesn't work on a SPARC otherwise.

-- 
	Keith Gorlen			phone: (301) 496-1111
	Building 12A, Room 2033		FAX: (301) 402-0007
	National Institutes of Health	uucp: uunet!kgorlen%alw.nih.gov
	Bethesda, MD 20892		Internet: kgorlen@alw.nih.gov