#define __USE_MISC
#include <stdlib.h>             /* Conversion routines are here         */
#include <stdio.h>		/* Standard I/O routines		*/
#include <ctype.h>		/* Character classifications		*/
#include <stdarg.h>		/* Standard variable argument package	*/
#include <errno.h>		/* Error numbers			*/
#include <limits.h>		/* Limits on numbers			*/
#include "file2.h"              /* File definitions                     */
#include "internal.h"		/* Internal definitions for STDIO	*/
#include "output.h"             /* Local definitions                    */

#include <trace.h>
/*
 * Purpose:
 *	Output a string to the output stream.
 *
 * Entry:
 *	stream - stream to be used for the output
 *	descriptor - descriptor for the string length, padd, etc.
 *	str - string to be written
 *
 * Exit:
 *	The number of characters written to the output stream.
 *
 */

static int strout (FILE *stream, DESCRIPTOR *descriptor, char *str);
static int strout (FILE *stream, DESCRIPTOR *descriptor, char *str)
    {
    int len;		/* Length of the output string			*/
    int size;		/* # of characters of the string to write	*/
    int i;		/* Temp counter					*/
    int pad;		/* Character to be used in padding the string	*/
    int osize;		/* # of characters total that will be written	*/
    FUNC_ENTRY ("strout");
/*
 *    Initialize to process the entry
 */
    pad = (descriptor->use_space) ? ' ' : '0';    /* Character for padding  */
    if (str == (char *) NULL)
	{
	str = "(null)";
	}
/*
 *    Determine the string length
 */
    len = strlen(str);
    if (descriptor->decimals != DEFAULT && descriptor->decimals < len)
	{
	len = descriptor->decimals;
	}
/*
 *    Size of the resulting string
 */
    osize =
    size  = (descriptor->size < len) ? len : descriptor->size;
/*
 *    Insert the sign of the string if it is a number and padding is
 *    in effect.
 */
    if (descriptor->is_num)
        {
	if (pad != ' ')
	    {
	    if (*str == '-' || *str == '+' || *str == ' ')
	        {
		putc (*str, stream);
	        ++str;
	        --size;
	        --len;
	        }
/*
 *    Insert the hexadecimal prefix if that is required
 */
	    if (*str == '0')
	        {
		if (str[1] == 'x' || str[1] == 'X')
		    {
		    putc (*str, stream);
		    ++str;
		    putc (*str, stream);
		    ++str;
		    size -= 2;
		    len  -= 2;
		    }
	        }
            }
        }
/*
 *    If the field is to be right justified then do so now
 */
    if (descriptor->right_just)
	{
	for (i = size-len; i > 0; --i)
	    {
	    putc (pad, stream);
	    }
	size = len;
	}
/*
 *    Now output the string
 */
    while (*str != '\0' && len > 0)
	{
	putc (*str, stream);
	++str;
	--len;
	--size;
	}
/*
 *    Append any trailing spaces so that the format is filled out
 */
    for (i = size-len; i > 0; --i)
	{
	putc (' ', stream);
	}
/*
 *    Return the size of the output field
 */
    FUNC_EXIT ("strout");
    return(osize);
    }

/************************************************************************
 *
 * Function:    decout
 *
 * Purpose:
 *	Write a fixed point value in decimal format to the output stream.
 *
 * Entry:
 *	stream - stream to be used for the output
 *	descriptor - descriptor for the string length, padd, etc.
 *	val - value to be written
 *
 * Exit:
 *	The number of characters written to the output stream.
 */

static int decout (FILE *stream, DESCRIPTOR *descriptor, long val);
static int decout (FILE *stream, DESCRIPTOR *descriptor, long val)
    {
    char space [CVTMAX];	   /* Editing buffer area		*/
    int  neg;			   /* Sign of the input value		*/
    int  min_digits;               /* Minimum number of digits to edit  */
    char *pt = &space[CVTMAX - 1]; /* Pointer to the output text area	*/
    FUNC_ENTRY ("decout");
/*
 *    Compute the minimum number of digits to be edited.
 */
    min_digits = descriptor->decimals;
    if (min_digits == DEFAULT)
        {
	min_digits = 0;
        }
    else
        {
	if (min_digits > EDITMAX)
	    {
	    min_digits = EDITMAX;
	    }
        }
/*
 *    Insert the trailing null character
 */
    *pt-- = '\0';
/*
 *    If the value is negative then remeber the sign for the end
 */
    if (val < 0)
	{
	val = -val;
	neg = 1;
	}
    else
        {
	neg = 0;
        }
/*
 *    Insert the next decimal digit into the output stream
 */
    do
	{
	*pt-- = (val % 10) + '0';
	val /= 10;
	}
    while (--min_digits > 0 || val != 0);
/*
 *    Insert the (leading) sign if required
 */
    if (neg)
	{
	*pt-- = '-';
	}
    else
	{
	if (descriptor->sign)
	    {
	    *pt-- = '+';
	    }
	else
	    {
	    if (descriptor->pad)
		{
		*pt-- = ' ';
		}
	    }
	}
/*
 *    Insert the string into the output stream
 */
    descriptor->decimals = DEFAULT;
    FUNC_EXIT ("decout");
    return (strout (stream, descriptor, ++pt));
    }

/************************************************************************
 *
 * Function:	octout
 *
 * Purpose:
 *	Write a fixed point value in octal format to the output stream.
 *
 * Entry:
 *	stream - stream to be used for the output
 *	descriptor - descriptor for the string length, padd, etc.
 *	val - value to be written
 *
 * Exit:
 *	The number of characters written to the output stream.
 *
 */

static int octout (FILE *stream, DESCRIPTOR *descriptor, unsigned long val);
static int octout (FILE *stream, DESCRIPTOR *descriptor, unsigned long val)
    {
    char space [CVTMAX];	   /* Editing buffer area		*/
    int	 min_digits;		   /* Minimum number of digits to edit	*/
    char *pt = &space[CVTMAX - 1]; /* Pointer to the output text area	*/
    FUNC_ENTRY ("outout");
/*
 *    Compute the minimum number of digits to be edited.
 */
    min_digits = descriptor->decimals;
    if (min_digits == DEFAULT)
	{
	min_digits = 0;
	}
    else
	{
	if (min_digits > EDITMAX)
	    {
	    min_digits = EDITMAX;
	    }
	}
/*
 *    Append the trailing null to the string
 */
    *pt--= '\0';
/*
 *    Edit the octal number
 */
    do
	{
	*pt-- = (val & 07) + '0';
	val = (val >> 3) & 0x1FFFFFFFl;
	}
    while ( --min_digits > 0 || val != 0);
/*
 *    Insert the leading "0" if requested
 */
    if (descriptor->alt_form)
	{
	*pt-- = '0';
	}
/*
 *    Write the data to the output stream
 */
    descriptor->decimals = DEFAULT;
    FUNC_EXIT ("outout");
    return (strout (stream, descriptor, ++pt));
    }

/*************************************************************************
 *
 * Function:	hexout
 *
 * Purpose:
 *	Write a fixed point value in hexadecimal format to the output stream.
 *
 * Entry:
 *	stream - stream to be used for the output
 *	descriptor - descriptor for the string length, padd, etc.
 *	val - value to be written
 *
 * Exit:
 *	The number of characters written to the output stream.
 */

static int hexout (FILE *stream, DESCRIPTOR *descriptor, unsigned long val);
static int hexout (FILE *stream, DESCRIPTOR *descriptor, unsigned long val)
    {
    static char digits[2][16] =
	{
	{'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'},
	{'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}
        };
    
    char space [CVTMAX];	   /* Editing buffer area		*/
    char *pt = &space[CVTMAX - 1]; /* Pointer to the output text area	*/
    int  min_digits;               /* Minimum number of digits to edit  */

    char *d = &digits [descriptor->type == 'X' ? 1 : 0] [0];
    FUNC_ENTRY ("hexout");
/*
 *    Compute the minimum number of digits to be edited.
 */
    min_digits = descriptor->decimals;
    if (min_digits == DEFAULT)
        {
	min_digits = 0;
        }
    else
        {
	if (min_digits > EDITMAX)
	    {
	    min_digits = EDITMAX;
	    }
        }
/*
 *    Insert the trailing null because we process the data right to left.
 */
    *pt-- = '\0';
/*
 *    Edit the number
 */
    do
	{
	*pt-- = d [val & 0x0F];
	val = (val >> 4) & 0x0FFFFFFFL;
	}
    while ( --min_digits > 0 || val != 0);
/*
 *    Insert the 0X modifier if requested
 */
    if (descriptor->alt_form)
	{
	*pt-- = descriptor->type;
	*pt-- = '0';
	}
/*
 *    Write the data to the output stream
 */
    descriptor->decimals = DEFAULT;
    FUNC_EXIT ("hexout");
    return (strout (stream, descriptor, ++pt));
    }

/***********************************************************************
 *
 * Function:      unsout
 *
 * Purpose:
 *	Write a fixed point value in unsigned decimal format to the output
 *	stream.
 *
 * Entry:
 *	stream - stream to be used for the output
 *	descriptor - descriptor for the string length, padd, etc.
 *	val - value to be written
 *
 * Exit:
 *	The number of characters written to the output stream.
 */

static int unsout (FILE *stream, DESCRIPTOR *descriptor, unsigned long val);
static int unsout (FILE *stream, DESCRIPTOR *descriptor, unsigned long val)
    {
    static
    int power2[13] = {8, 4, 6, 3, 8, 4, 7, 4, 1, 2, 0, 0, 0};

    char  space [CVTMAX];	   /* Editing buffer area		*/
    char *pt = &space[CVTMAX - 1]; /* Pointer to the output text area	*/
    int   carry;		   /* Carry out of previous digit	*/
    int   min_digits;              /* Minimum number of digits to edit  */
    int   i;
    int   temp;
    int   add;				/* Additive factor for sign	*/
    FUNC_ENTRY ("unsout");
/*
 *    Compute the minimum number of digits to be edited.
 */
    min_digits = descriptor->decimals;
    if (min_digits == DEFAULT)
        {
	min_digits = 0;
        }
    else
        {
	if (min_digits > EDITMAX)
	    {
	    min_digits = EDITMAX;
	    }
        }
/*
 *    Mark the end of the string as we will be filling the string in from the
 *    right to left direction.
 */
    carry = 0;
    *pt-- = '\0';
/*
 *    If the value is negative then set the initial carry condition and remove
 *    the most significant bit.
 */
    if (val & 0x80000000l)
	{
	val &= ~0x80000000l;
	add = 1;
	}
    else
	{
	add = 0;
	}
/*
 *    Process the carry-out from the prior divide
 */
    i = 0;
    do
	{
	if (add)
	    {
	    temp = (val%10l)+power2[i]+carry;   /* Compute the digit value  */
	    if (temp >= 10l)		/* If the value is too		*/
		{			/* large then reduce it by	*/
		temp -= 10l;		/* 10 and carry into the	*/
		carry = 1;		/* next stage.			*/
		}
	    else
		{
		carry = 0;		/* No need to carry bits	*/
		}
	    }
/*
 *    Process a digit where the entry was not too large
 */
	else
	    {
	    temp = val%10;		/* Just make it modulo 10	*/
	    }
	*pt-- = temp+'0';		/* Insert the character		*/
	val /= 10;			/* Compute the new value	*/
	++i;				/* and point to next power	*/
	--min_digits;                   /* Drop the digit counter       */
	}
    while (val != 0 || carry != 0 || (add && power2[i] != 0));
/*
 *    The upper digits are always zero. Insert them.
 */
    while (min_digits-- > 0)
        {
	*pt-- = '0';
        }
/*
 *    End of the string. Write the data to the output stream.
 */
    descriptor->decimals = DEFAULT;
    FUNC_EXIT ("unsout");
    return (strout (stream, descriptor, ++pt));
    }

/***********************************************************************
 *
 * Function:    fout
 *
 * Purpose:
 *	Write floating point value to the output module in "f" format.
 *
 * Entry:
 *	stream - stream to be used for the output
 *	descriptor - descriptor for the string length, padd, etc.
 *	val - value to be written
 *
 * Exit:
 *	The number of characters written to the output stream.
 */

static int fout (FILE *stream, DESCRIPTOR *descriptor, double val);
static int fout (FILE *stream, DESCRIPTOR *descriptor, double val)
    {
    int i;			/* General counter and temp		*/
    int decpt;			/* # of decimal places			*/
    int ndig;			/* # of bytes in fcvt output string	*/
    int cnt;			/* digit counter			*/
    char *pt;			/* Character pointer			*/
    int sign;			/* Sign of the mantissa			*/
    char *digits;		/* Pointer to the digit from fcvt	*/
    char space [CVTMAX];	/* Editing buffer area			*/
    FUNC_ENTRY ("fout");
/*
 *    Do the conversion of binary to ascii
 */
    ndig = (descriptor->decimals == DEFAULT) ? 6 : descriptor->decimals;
    digits = fcvt (val, ndig, &decpt, &sign);
/*
 *    Insert the sign if desired
 */
    pt = space;
    if (sign)
	{
	*pt++= '-';
	}
    else
	{
	if (descriptor->sign)
	    {
	    *pt++= '+';
	    }
	else
	    {
	    if (descriptor->pad)
		{
		*pt++= ' ';
		}
	    }
	}
/*
 *    Ensure that there is at least one whole digit before the decimal point.
 *    It is bad form to edit 1/2 as ".5" when it should be "0.5".
 */
    if (decpt < 1)
	{
	*pt++= '0';
	}
/*
 *    Generate the whole digit positions
 */
    for (i = 0; decpt >= 1; --decpt, ++i)
	{
	if (i < MAXDIGITS)
	    {
	    *pt++ = digits[i];
	    }
	else
	    {
	    *pt++ = '0';
	    }
	}
/*
 *    Add in the decimal point
 */
    *pt++= '.';
/*
 *    Follow it with the number of zeros to the first significant fractional
 *    digit.
 */
    for (cnt = 0; cnt < ndig; cnt++)
	{
	if (decpt < 0)
	    {
	    *pt++ = '0';
	    ++decpt;
	    }
/*
 *    Use the decimal positions from the actual number
 */
	else
	    {
	    if (i < MAXDIGITS)
		{
		*pt++ = digits[i++];
		}
/*
 *    More digits are required then are available. This is simple. All of the
 *    remaining positions are zero.
 */
	    else
		{
		*pt++ = '0';
		}
	    }
	}
/*
 *    Remove trailing zeros if it was not desired to keep them for "G" format.
 */
    if (!descriptor->alt_form &&
         (descriptor->type == 'g' || descriptor->type == 'G'))
	{
	while (pt[-1] == '0')
	    {
	    pt--;
	    }
/*
 *    Discard the decimal point as well
 */
	if (pt[-1] == '.')
	    {
	    pt--;
	    }
	}
/*
 *    Remove the decimal point if that is the only character in the buffer and
 *    it is not desired to retain the decimal point.
 */
    else
	{
	if (ndig == 0 && ! descriptor->alt_form)
	    {
	    pt--;
	    }
	}
/*
 *    Mark the end of the string and insert it into the output stream
 */
    *pt = '\0';
    descriptor->decimals = DEFAULT;
    FUNC_EXIT ("fout");
    return (strout (stream, descriptor, space));
    }

/**********************************************************************
 *
 * Function:         eout
 *
 * Purpose:
 *	Write floating point value to the output module in "e" format.
 *
 * Entry:
 *	stream - stream to be used for the output
 *	descriptor - descriptor for the string length, padd, etc.
 *	val - value to be written
 *
 * Exit:
 *	The number of characters written to the output stream.
 */

static int eout (FILE *stream, DESCRIPTOR *descriptor, double val);
static int eout (FILE *stream, DESCRIPTOR *descriptor, double val)
    {
    int i;			/* General counter and temp		*/
    int decpt;			/* # of decimal places			*/
    int ndig;			/* # of bytes in fcvt output string	*/
    char *pt;			/* Character pointer			*/
    int sign;			/* Sign of the mantissa			*/
    char *digits;		/* Pointer to the digit from fcvt	*/
    char space [CVTMAX];	/* Editing buffer area			*/
    char printzero;		/* TRUE if needs to print zeros		*/
    int pten;			/* Power of 10 to use in conversion	*/
    FUNC_ENTRY ("eout");
/*
 *    Do the conversion of the binary to ascii (again)
 */
    ndig   = (descriptor->decimals == DEFAULT) ? 6 : descriptor->decimals;
    digits = ecvt (val, ++ndig, &decpt, &sign);
/*
 *    If the value is not zero then drop the number of decimals
 */
    if (val != 0.0)
	{
	--decpt;
	}
/*
 *    Insert the sign of the value
 */
    pt = space;
    if (sign)
	{
	*pt++= '-';
	}
    else
	{
	if (descriptor->sign)
	    {
	    *pt++= '+';
	    }
	else
	    {
	    if (descriptor->pad)
		{
		*pt++= ' ';
		}
	    }
	}
/*
 *    Insert the units digit and the decimal point into the output stream
 */
    *pt++ = digits[0];
    *pt++ = '.';
/*
 *    Append the fractional digits to the output string
 */
    for (i=1 ; i < ndig ;)
	{
	*pt++ = digits[i++];
	}
/*
 *    Remove trailing zeros from the fraction positions if required
 */
    if (!descriptor->alt_form &&
        (descriptor->type == 'g' || descriptor->type == 'G'))
	{
	while (pt[-1] == '0')
	    {
	    --pt;
	    }
/*
 *    Remove the decimal point from the number
 */
	if (pt[-1] == '.')
	    {
	    --pt;
	    }
	}
/*
 *    Not general output. It must have been "E" output. Delete the decimal
 *    point if it is the only character in the buffer and it was not desired
 *    that it be left.
 */
    else
	{
	if (ndig == 1 && !descriptor->alt_form)
	    {
	    --pt;
	    }
	}
/*
 *    Insert the "E" code for exponent seperator
 *    (This routine is also called for the "g" format, so use upper case
 *    test rather than simply using the descriptor type.)
 */
    *pt++ = isupper (descriptor->type) ? 'E' : 'e';
/*
 *    Add the sign of the exponent
 */
    if (decpt < 0)
	{
	*pt++ = '-';
	decpt = -decpt;
	}
    else
	{
	*pt++= '+';
	}
/*
 *    Insert the exponent into the output string
 */
    printzero = 0;
    for (pten = 10000; pten > 0; pten /= 10)
	{
	if (printzero || pten <= 10 || decpt >= pten)
	    {
	    printzero = 1;
	    *pt++ = (decpt / pten) + '0';
	    decpt %= pten;
	    }
	}
/*
 *    Write the output characters to the stream
 */
    *pt = '\0';
    descriptor->decimals = DEFAULT;
    FUNC_EXIT ("eout");
    return (strout (stream, descriptor, space));
    }

/************************************************************************
 *
 * Function:     gout
 *
 * Description:
 *    Write a floating point value to the output stream in "g" format.
 *
 * Entry:
 *	stream - stream to be used for the output
 *	descriptor - descriptor for the string length, padd, etc.
 *	val - value to be written
 *
 * Exit:
 *	The number of characters written to the output stream.
 */

static int gout (FILE *stream, DESCRIPTOR *descriptor, double val);
static int gout (FILE *stream, DESCRIPTOR *descriptor, double val)
    {
    int decpt;                     /* Number of decimal digits             */
    int sign;                      /* Sign of the mantissa                 */
    char *digits;                  /* Pointer to the ecvt string           */
    FUNC_ENTRY ("gout");
/*
 *    Validate the number of decimal positions
 */
    if (descriptor->decimals == DEFAULT)
	{
	descriptor->decimals = 6;
	}

    if (descriptor->decimals < 1)
	{
	descriptor->decimals = 1;
	}
/*
 *    Convert the number to a decimal string and exponent
 */
    digits = ecvt(val, descriptor->decimals, &decpt, &sign);
/*
 *    If the value will not fit then use exponential format
 */
    if (decpt <= -4 || decpt > descriptor->decimals)
	{
	--(descriptor->decimals);
	return (eout (stream, descriptor, val));
	}
/*
 *    If the value will fit then use a floating point format
 */
    else
	{
	descriptor->decimals -= decpt;
	return (fout (stream, descriptor, val));
	}
    FUNC_EXIT ("gout");
    }

/***************************************************************************
 *
 * Function:   _doprnt
 *
 * Description:
 *    Fetch the data items from the arglist and edit them according to the
 *    format string. The result is written to the file stream.
 *
 *    Arguments are denoted in the format string as having a leading "%"
 *    character.
 *
 * Input:
 *    format   - pointer to the format string
 *    arglist  - vector of argument addresses and values
 *    stream   - output file to which the data is to be written.
 *
 * Returns:
 *    The number of characters written to the output or EOF to indicate
 *    an error condition on the write.
 */

int _doprnt (const char *format, va_list args, FILE *stream)
    {
    DESCRIPTOR descriptor;
    char str[4];
    int  cnt = 0;
    int  more;
    FUNC_ENTRY ("_doprnt");
/*
 *    Generate an error if the specified file is not writable
 */
    if ((stream->_flag & _IOWRT) == 0)
	{
	errno = EBADF;
	FUNC_EXIT ("_doprnt");
	return(-1);
	}
/*
 *    If there is no format string then fake one up
 */
    if (format == (char *) NULL)
	{
	format = "(NULL)";
	}
/*
 *    Process the non-format character groups.
 */
    while (*format != '\0')
	{
	if (*format != '%')
	    {
	    putc (*format, stream);
	    ++format;
	    ++cnt;
	    continue;
	    }
/*
 *      % found in string. Output the % if it is represented as %%.
 */
	if (*++format == '%')
	    {
	    putc (*format, stream);
	    ++format;
	    ++cnt;
	    continue;
	    }
/*
 *    Initialize the descriptor to hold the information about the output
 */
	descriptor.size       =
	descriptor.decimals   = DEFAULT;
    
	descriptor.is_num     =
	descriptor.use_space  =
	descriptor.is_long    =
	descriptor.right_just = 1;

	descriptor.sign       =
	descriptor.pad        =
	descriptor.alt_form   = 0;
/*
 *    Honor the leading format codes
 */
	more = 1;
	while (more)
	    {
	    switch (*format)
	        {
	    case '-':
		descriptor.right_just = 0;
		break;

	    case '+':
		descriptor.sign       = 1;
		break;

	    case ' ':       
		descriptor.pad        = 1;
		break;

	    case '#':       
		descriptor.alt_form    = 1;
		break;

	    default:        
		more = 0;
                break;
		}

	    if (more)
	        {
		++format;
	        }
	    }
/*
 *    If the number contains a leading zero then use zero stuffing
 */
	if (*format == '0')
	    {
	    ++format;
	    descriptor.use_space = 0;
	    }
	else
	    {
	    if (*format == '.')
	        {
		descriptor.use_space = 0;
	        }
	    }
/*
 *    Collect the field width if one is supplied
 */
	if (isdigit (*format))
	    {
	    descriptor.size = 0;
	    while (isdigit (*format))
	        {
		descriptor.size *= 10;
		descriptor.size += (toascii (*format) - toascii ('0'));
		++format;
	        }
	    }
/*
 *    Fetch the variable field width
 */
	else
	    {
	    if (*format == '*')
	        {
		descriptor.size = va_arg (args, int);
		++format;
	        }
	    }
/*
 *    Accept the decimal width if necessary
 */
	if (*format == '.')
	    {
	    ++format;
	    if (isdigit(*format))
	        {
		descriptor.decimals = 0;
		while (isdigit(*format))
		    {
		    descriptor.decimals *= 10;
		    descriptor.decimals += (toascii (*format) - toascii ('0'));
		    ++format;
		    }
	        }
	    else
	        {
		if (*format == '*')
		    {
		    descriptor.decimals = va_arg(args, int);
		    ++format;
		    }
	        }
	    }
/*
 *    Ignore leading blanks to the argument type indicator
 */
	while (*format == ' ')
	    {
	    ++format;
	    }
/*
 *    Determine the size of the number.
 */
	switch (*format)
	    {
	case 'l':  /* long */
	    descriptor.is_long = 1;
	    ++format;
	    break;

	case 'L':  /* longlong */
	    descriptor.is_long = 2;
	    ++format;
	    break;

	case 'h':  /* halfword (short) */
	    descriptor.is_long = 0;
	    ++format;
	    break;

	default:   /* not one of these. */
	    break;
	    }
/*
 *    Process the type string
 */
	descriptor.type = *format++;
	if (descriptor.type == 's')
	    {
	    descriptor.is_num = 0;
	    }

	if (descriptor.type == '\0')
	    {
	    break;
	    }
/*
 *    Branch on the type of descriptor to be used.
 */
	switch (descriptor.type)
	    {
	case '%':
	    cnt += strout (stream, &descriptor, "%");
	    break;

	case 's':
	    cnt += strout (stream, &descriptor, va_arg (args, char *));
	    break;

	case 'd':
	    if (descriptor.is_long)
	        {
		cnt += decout (stream,
			       &descriptor,
			       va_arg(args,long));
	        }
	    else
	        {
		cnt += decout (stream,
			       &descriptor,
			       (long) (va_arg (args, short)));
	        }
	    break;

	case 'o':
	    if (descriptor.is_long)
	        {
		cnt += octout (stream,
			       &descriptor,
			       va_arg (args, unsigned long));
	        }
	    else
	        {
		cnt += octout (stream,
			       &descriptor,
			       (unsigned long) va_arg (args, unsigned short));
	        }
	    break;

	case 'p':
	    descriptor.alt_form = 1;
	    cnt += hexout (stream, &descriptor, (long) args);
	    (void) va_arg (args, unsigned long);
	    break;
    
	case 'x':
	case 'X':
	    if (descriptor.is_long)
	        {
		cnt += hexout (stream,
			       &descriptor,
			       va_arg (args, unsigned long));
	        }
	    else
	        {
		cnt += hexout (stream,
			       &descriptor,
			       (unsigned long) va_arg (args, unsigned short));
	        }
	    break;

	case 'u':
	    if (descriptor.is_long)
	        {
		cnt += unsout (stream,
			       &descriptor,
			       va_arg (args, unsigned long));
	        }
	    else
	        {
		cnt += unsout (stream,
			       &descriptor,
			       (unsigned long)va_arg (args, unsigned short));
	        }
	    break;

	case 'c':
	    str[0] = (char) va_arg (args, int);
	    str[1] = '\0';
	    cnt += strout (stream, &descriptor, &str[0]);
	    break;

	case 'e':
	case 'E':
	    cnt += eout (stream, &descriptor, va_arg (args, double));
	    break;

	case 'f':
	    cnt += fout (stream, &descriptor, va_arg (args, double));
	    break;

	case 'g':
	case 'G':
	    cnt += gout (stream, &descriptor, va_arg (args, double));
	    break;
	    
	default:
	    str[0] = (char) descriptor.type;
	    str[1] = '\0';
	    cnt += strout(stream, &descriptor, &str[0]);
	    break;
	    }
        }
/*
 *    Return the character count written to the string or EOF to indicate
 *    an error condition.
 */
    if (cnt == 0 && ferror (stream))
        {
	cnt = -1;
        }

    FUNC_EXIT ("_doprnt");
    return (cnt);
    }
