/*
 * 5799-WZQ (C) COPYRIGHT IBM CORPORATION 1986,1987,1988
 * LICENSED MATERIALS - PROPERTY OF IBM
 * REFER TO COPYRIGHT INSTRUCTIONS FORM NUMBER G120-2083
 */
/* $Header:sprintf.c 12.0$ */
/* $ACIS:sprintf.c 12.0$ */
/* $Source: /ibm/acis/usr/sys/cacons/RCS/sprintf.c,v $ */

#if !defined(lint) && !defined(NO_RCS_HDRS)
static char *rcsid = "$Header:sprintf.c 12.0$";
#endif

#ifdef DEBUG
#include "aed.h"

#if NAED > 0
/*
 * This is my sprintf for use in the kernel.
 */

/*
 * states for the printing of characters.
 */
#define START 0
#define POSSIBLE_ARG 1
#define MAXNUM 30

#define CONVERSION_CHAR '%'

/*
 * The different arguments. %s,%d,%x or %c are the only valid arguments.
 */
#define DEC 'd'
#define HEX 'x'
#define STR 's'
#define CHR 'c'

/*
 * Does an in place reverse of the characters in s. (See "The C Programming
 * Language" by Kernigan and Richie)
 */
reverse(s)
register char *s;
{

	register i,j;
	char c;

	for (i = 0, j = strlen(s) - 1; i < j; i++,j--) {
		c = s[i];
		s[i] = s[j];
		s[j] = c;
	}
}

/*
 * Like itoa in the stdio but it takes a 3rd number which is the base of the
 * number converted.  (NOTE: It assumes str is big enough.)
 * Returns a pointer to the last character written.
 */
char *
itos(n,str,base)
register unsigned long n;
register char *str;
register int base;
{
	register i,sign;
	register digit;

	/*
	 * If this is base 10 then a number can be negative.
	 */
	if (base == 10 && (sign = n & 0x80000000))
		n = -n;

	i = 0;
	do {	/*
		 * generate digits in reverse order.
		 */
		if ((digit = n % base) > 9)
			str[i++] = digit + 'A' - 10;
		else
			str[i++] = digit + '0';
		
	} while ((n /= base) > 0);

	if (base == 10 && sign)
		str[i++] = '-';

	str[i] = '\0';
	reverse(str);

	return(&str[i]);
}

char *
cp_str(str1,str2)
register char *str1;
register char *str2;
{
	/*
	 * This while loop copies in the null character which we remove
	 * with the -- on return.
	 */
	while (*str2++ = *str1++);

	return(--str2);
}

char *
chr_str(n,str)
int n;
char *str;
{
	*str++ = (char)n;

	return(str);
}

d_sprintf(str,args)
char *str;
char *args;
{
	register stack;
	register i;
	register state;

	stack = (int)(&args) + 4;

	state = START;
	for (i = 0; args[i] != '\0'; i++) {
		switch (state) {
		    case START:
				if (args[i] == CONVERSION_CHAR)
					state = POSSIBLE_ARG;
				else
					*str++ = args[i];
				break;

		    case POSSIBLE_ARG:
				switch (args[i]) {
				    case DEC:
					str = itos(*(int *)stack,str,10);
					stack += sizeof(int);
					break;

				    case HEX:
					str = itos(*(int *)stack,str,16);
					stack += sizeof(int);
					break;

				    case STR:
					str = cp_str(*(char **)stack,str);
					stack += sizeof(char *);
					break;

				    case CHR:
					str = chr_str(*(int *)stack,str);
					stack += sizeof(int);
					break;

				    default:
					*str++ = args[i];
				}
				state = START;
		}
	}
	*str = '\0';
}
#endif /* NAED */
#endif /* DEBUG */
