/*	EDSPRF.C  a very simple sprintf for TED.		*/
/*								*/
/*	27-JUN-1985 10:06  Brian Nelson				*/
/*								*/
/*	Written to avoid pulling in I/O modules from the Decus	*/
/*	C compiler runtime library for the PDP-11 version.	*/



#define	then
#define	CR	015
#define	LF	012

union argtype	{
		char	*spoint ;
		char	cval  ;
		int	intval ;
		int	octval ;
		int	hexval ;
		} ;


sxprintf(s,fmt,arg)
{
	sprf_(s,fmt,&arg) ;
}

xprintf(fmt,arg)
{
	char s[256] ;
	sprf_(s,fmt,&arg) ;
	putbin(s,strlen(s)) ;
}

static sprf_(s,fmt,arg)
char *s,*fmt ;
union argtype *arg ;
{

	int radix,temp,value ;
	register char *cp,ch ;
	int fw,i ;
	char nbuffer[20] ;

	*s = 0 ;
	fw = 0 ;
	radix = 10 ;
	while ( *fmt != 0 ) {
	  if ( *fmt == '%' )
	    then {
		if ( isdigit( *(++fmt) ) )
		  then	{
			fw = 0 ;
			while ( isdigit(*fmt) )
			  fw = fw*10 + (*fmt++ - '0') ;
			} ;
		switch(ch = *fmt) {
		  case 'c':
		  case 'C':
			for (i=fw-1; i>0; i--) *s++ = ' ' ;
			*s++ = (arg++)->cval ;
			*s = 0 ;
			fw = 0 ;
			fmt++ ;
			break ;
		  case 's':
		  case 'S':
			cp = (arg++)->spoint ;
			for (i=fw-strlen(cp); i>0; i--) *s++ = ' ' ;
			while ( *s = *cp++ ) s++ ;
			fw = 0 ;
			fmt++ ;
			break ;
		  case 'd':
		  case 'D':
		  case 'o':
		  case 'O':
		  case 'X':
		  case 'x':
			switch( ch=tolower(ch) ) {
			  case 'd': radix = 10 ;
				    break ;
			  case 'o': radix = 8 ;
				    break ;
			  case 'x': radix = 16 ;
				    break ;
				} ;
			cp = &nbuffer[20] ;
			*(--cp) = 0 ;
			if ( ch == 'd' && (value = arg->intval) < 0 )
			   value = -value ;
			do {
			   temp = value % radix ;
			   *(--cp) = temp + ((temp < 10) ? '0':('A'-10)) ;
			   }
			while ((value /= radix) != 0);
			if ( (arg++)->intval < 0 && ch == 'd') *(--cp) = '-' ;
			for (i=fw-strlen(cp); i>0; i--) *s++ = ' ' ;
			while ( *s = *cp++ ) s++ ;
			fw = 0 ;
			fmt++ ;
			break ;
		  case '\0':
			break ;
			} ;
		}
	  else	{
		if ( *fmt == LF ) *s++ = CR ;
		*s++ = *fmt++ ;
		*s = 0 ;
		} ;
	} ;			/* end while *fmt != 0 */
}


static isdigit(c)
char c;
{
	return( c >= '0' && c <= '9' ) ;
}

static tolower(c)
char c ;
{
	return( ( c >= 'A' && c <= 'Z' ) ? c | 040 : c ) ;
}

static strlen(s)
char *s ;
{
	register int len ;

	len = 0 ;
	while ( *s++ ) len++ ;
	return(len) ;
}
