/*--------------------------------------------------------------------*/
/* H8S,H8/300 SERIES C Compiler Ver. 1.0                              */
/* Copyright (C) 1994 Hitachi, Ltd.                                   */
/* Licensed Material of Hitachi,Ltd.                                  */
/*--------------------------------------------------------------------*/
/***********************************************************************/
/* SPEC;                                                               */
/*  NAME = _fmtout : write data with format;                           */
/*         __fmtout :  if _NO_FLOAT defined, not support float         */
/*                                                                     */
/*  FUNC = this module do the following functions;                     */
/*         (1) convert integer to string                               */
/*         (2) convert double to string                                */
/*                                                                     */
/*  CLAS = UNIT;                                                       */
/*                                                                     */
/* END;                                                                */
/***********************************************************************/
#define _NO_FLOAT                                         /* A 3V4027 */
#include "lstdio.h"
#define  _IOPROT 1
#include "h2lfun.h"
#include "lstdarg.h"
#include "lstdlib.h"
#include "lctype.h"
#include "lstring.h"
#include "llimits.h"
#ifdef _NO_FLOAT                                       /* A P3V252-2L */
#define _fmtout __fmtout                               /* A P3V252-2L */
#endif                                                 /* A P3V252-2L */
#include "e_fmtou.h"

#define fmtflgon(status) (p_data2->_fmtflg |=  (status))   /* P3V257 C */
#define fmtflgof(status) (p_data2->_fmtflg &= ~(status))   /* P3V257 C */
#define fmtflgck(status) (p_data2->_fmtflg &   (status))   /* P3V257 C */

#define FORMERR  1                          /* format error flag */
#define LEFTADJ  2                          /* conversion spec flag, '-' */
#define ONLYONE  4                          /* conversion spec flag, '#' */
#define SIGNPLS  8                          /* conversion spec flag, '+' */
#define SIGNSPC 16                          /* conversion spec flag, ' ' */
                                            /*             not pad char. */
#define GCONVRT 32                          /* g or G flag       */



/***********************************************************************/
/*                                                                     */
/* common area :                                                       */
/*                                                                     */
/***********************************************************************/


/* static long _outkind;          *                            * P3V257 D */
/* static char _fmtflg;           * format analize flag        * P3V257 D */
/* static char *_str;             *                            * P3V257 D */
/* static long _outch;            * output character counter   * P3V257 D */

/* static char _padchar;          * pad character              * P3V257 D */
/* static long _width;            * field width                * P3V257 D */
/* static long _prec;             *                            * P3V257 D */
/* static char *_prec_addr0;      * prec '0' insert address    * P3V257 D */
/* static char *_prec_addr1;      * prec '0' insert address    * P3V257 D */
/* static char *_prec_addr2;      * prec '0' insert address    * P3V257 D */
/* static long _prec_ins0;        * prec '0' insert char count * P3V257 D */
/* static long _prec_ins1;        * prec '0' insert char count * P3V257 D */
/* static long _prec_ins2;        * prec '0' insert char count * P3V257 D */
/* static long _with_ins;         * remain width char count    * P3V257 D */
/* static long _parasize;         * type of parameter          * P3V257 D */
/* static int (*_sofun)(int, FILE *);           * V2.0 A * P3V257(1) D */

static void _ltostr(long, char*, int, _DATA2 *);              /* P3V257 C */

#ifndef _NO_FLOAT                                      /* A P3V252-2L */
static void _dtostr(double, char*, int, _DATA2 *);            /* P3V257 C */
static void _round(char*, long);
#endif                                                 /* A P3V252-2L */

static void _putstr(char*, long, _DATA1 *);                   /* P3V257 C */
static void _putnull(_DATA1 *);                               /* P3V257 C */
static int  _puterr(_DATA1 *);                                /* P3V257 C */

/***********************************************************************/
/*                                                                     */
/* main routine :                                                      */
/*                                                                     */
/***********************************************************************/
int _fmtout(outkind,ofun,str,format,arg)   /* V2.0 C */
int           outkind;
int           (*ofun)(int, FILE *);        /* V2.0 A */
FILE          *str;
const char    *format;
char          *arg;
{

    _DATA1   _data1;                                    /* P3V257 A */
    _DATA1   *p_data1 = &_data1;                        /* P3V257 A */
    _DATA2   _data2;                                    /* P3V257 A */
    _DATA2   *p_data2 = &_data2;                        /* P3V257 A */
/*  char     _fmtflg  = (char)0;                         * P3V257(1) D */

    long int ivalue;
#ifndef _NO_FLOAT                                      /* A P3V252-2L */
    double   dvalue;
#endif                                                 /* A P3V252-2L */
    long int length,i,j;
    char     tbuf[128];
    char     *cp;
    char     *objp;
    char     *p;
    char     prec_char;
    long     w;

    p_data1 -> _outkind    = 0L;                        /* P3V257 A */
    p_data1 -> _str        = NULL;                      /* P3V257 A */
    p_data1 -> _outch      = 0L;                        /* P3V257 A */
    p_data2 -> _fmtflg     = (char)0;                   /* P3V257 A */
    p_data2 -> _padchar    = (char)0;                   /* P3V257 A */
    p_data2 -> _width      = 0L;                        /* P3V257 A */
    p_data2 -> _prec       = 0L;                        /* P3V257 A */
    p_data2 -> _prec_addr0 = NULL;                      /* P3V257 A */
    p_data2 -> _prec_addr1 = NULL;                      /* P3V257 A */
    p_data2 -> _prec_addr2 = NULL;                      /* P3V257 A */
    p_data2 -> _prec_ins0  = 0L;                        /* P3V257 A */
    p_data2 -> _prec_ins1  = 0L;                        /* P3V257 A */
    p_data2 -> _prec_ins2  = 0L;                        /* P3V257 A */
    p_data2 -> _with_ins   = 0L;                        /* P3V257 A */

    if (outkind==0){
        if (str==0){
            _errno = PTRERR;
            return(EOF);
        }
        if (flgck1(((FILE*)str),(_IORW|_IOREAD|_IOWRITE))==0){
            _errno = NOTOPN;
            return(EOF);
        }
        if (flgck1(((FILE*)str),_IORW)==0 &&
            flgck1(((FILE*)str),_IOREAD)!=0){
            _errno = EBADF;
            return(EOF);
        }
        if (flgck1(((FILE*)str),_IOERR)!=0)
            return(EOF);
        p_data1->_sofun=ofun;                  /* V2.0 A * P3V257(1) C */
    }

    p_data1 -> _outkind  = outkind;                       /* P3V257 C */
    p_data1 -> _str      = (char*)str;                    /* P3V257 C */
    p_data1 -> _outch    = 0;                             /* P3V257 C */
    p_data2 -> _fmtflg   = (char)0;                       /* P3V257 C */
    prec_char = (char)'0';

    if (_puterr(p_data1)!=0) return(EOF);                                 /* P3V257 C */
    for (;*format!='\0' && _puterr(p_data1)==0 && fmtflgck(FORMERR)==0;){ /* P3V257 C */
        if (*format=='%'){
            format++;
            p_data2->_fmtflg = (char)0;  /* all flag reset P3V257(1) C */
            p_data2 -> _prec_addr0 = tbuf;                /* P3V257 C */
            p_data2 -> _prec_addr1 = tbuf;                /* P3V257 C */
            p_data2 -> _prec_addr2 = 0;                   /* P3V257 C */
            p_data2 -> _prec_ins0  = 0;                   /* P3V257 C */
            p_data2 -> _prec_ins1  = 0;                   /* P3V257 C */
            p_data2 -> _prec_ins2  = 0;                   /* P3V257 C */
            p_data2 -> _with_ins   = 0;                   /* P3V257 C */
            for (;*format=='-' || *format=='+'||
                  *format==' ' || *format=='#';){
                 switch(*format){
                     case '-': fmtflgon(LEFTADJ);
                               break;
                     case '+': fmtflgon(SIGNPLS);
                               break;
                     case ' ': if (fmtflgck(SIGNPLS)==0)
                                   fmtflgon(SIGNSPC);
                               break;
                     case '#': fmtflgon(ONLYONE);
                               break;
                 }
                 format++;
            }

            p_data2 -> _padchar = ' ';                    /* P3V257 C */
            if (*format=='0'){
                p_data2 -> _padchar = (char)'0';          /* P3V257 C */
                format++;
            }
            p_data2 -> _width = 0;                        /* P3V257 C */
            if (*format=='*'){
                p_data2->_width = va_arg(arg,int);        /* P3V257 C */
                if (p_data2->_width < 0){                 /* P3V257 C */
                   fmtflgon(LEFTADJ);
                   p_data2->_width = -(p_data2->_width);  /* P3V257 C */
                }
                if (p_data2->_width > 512){               /* P3V257 C */
                   fmtflgon(FORMERR);
                   _errno=ECSPEC;
                }
                format++;
            }
            if (isdigit(*format)!=0){
                p_data2 -> _width = 0;                            /* P3V257 C */
                for (;isdigit(*format)!=0;){
                    w=(*format)-'0';
                    if (((512-w)/10) >= p_data2->_width)          /* P3V257 C */
                        p_data2->_width = p_data2->_width*10+w;   /* P3V257 C */
                    else{
                        fmtflgon(FORMERR);
                        _errno=ECSPEC;
                    }
                    format++;
                }
            }
            p_data2 -> _prec = -1;                                /* P3V257 C */
            if (*format=='.'){
                format++;
                if (*format=='*'){
                    p_data2->_prec = va_arg(arg,int);             /* P3V257 C */
                    if (p_data2->_prec < 0) p_data2->_prec=-1;    /* P3V257 C */
                    if (p_data2->_prec > 512){                    /* P3V257 C */
                        fmtflgon(FORMERR);
                        _errno=ECSPEC;
                    }
                    format++;
                }
                if (isdigit(*format)!=0){
                    p_data2->_prec = 0;                           /* P3V257 C */
                    for (;isdigit(*format)!=0;){
                        w=(*format)-'0';
                        if (((512-w)/10) >= p_data2->_prec)       /* P3V257 C */
                            p_data2->_prec = p_data2->_prec*10+w; /* P3V257 C */
                        else{
                            fmtflgon(FORMERR);
                            _errno=ECSPEC;
                        }
                        format++;
                    }
                }
            }
            p_data2->_parasize = ' ';                             /* P3V257 C */
            if (*format=='h' || *format=='l' || *format=='L'){
                p_data2->_parasize = *format;                     /* P3V257 C */
                format++;
            }

            switch (*format){
                case 'd':
                case 'i':
                case 'o':
                case 'u':
                case 'x':
                case 'X':
                          if (p_data2->_parasize=='l')            /* P3V257 C */
                              ivalue = va_arg(arg,long int);
                          else
                              if (p_data2->_parasize=='h')        /* P3V257 C */
                                  if (*format=='u' || *format=='X' ||
                                      *format=='x' || *format=='o')
                                      ivalue = (unsigned short int)
                                                       va_arg(arg,int);
                                  else
                                      ivalue = (short int)va_arg(arg,int);
                              else
                                  if (*format=='u' || *format=='X' ||
                                      *format=='x' || *format=='o')
                                      ivalue= (unsigned int)va_arg(arg,int);
                                  else
                                      ivalue= va_arg(arg,int);

                          if (p_data2->_prec==-1) p_data2->_prec = 1; /* P3V257 C */
                          _ltostr(ivalue,tbuf,(int)*format,p_data2);  /* P3V257 C */
                          cp = tbuf;
                          length = strlen(cp);
                          break;

#ifndef _NO_FLOAT                                      /* A P3V252-2L */
                case 'f':
                case 'e':
                case 'E':
                case 'g':
                case 'G': if (p_data2->_parasize=='L')                /* P3V257 C */
                              dvalue = va_arg(arg,long double);
                          else
                              dvalue = va_arg(arg,double);
                          if (p_data2->_prec==-1) p_data2->_prec = 6; /* P3V257 C */
                          _dtostr(dvalue,tbuf,(int)*format,p_data2);  /* P3V257 C */
                          cp = tbuf;
                          length = strlen(cp);
                          break;
#endif                                                 /* A P3V252-2L */

                case 'c': tbuf[0] = (char) va_arg(arg,int);
                          cp = tbuf;
                          length = 1;
                          p_data2->_prec_addr1 = tbuf;                     /* P3V257 C */
                          p_data2->_prec_ins1  = 0;                        /* P3V257 C */
                          p_data2->_with_ins   = p_data2->_width - length; /* P3V257 C */
                          break;

                case 's': cp = va_arg(arg,char *);
                          length = strlen(cp);
                          if (p_data2->_prec!=-1 && p_data2->_prec<length) /* P3V257 C */
                              length = p_data2->_prec;                     /* P3V257 C */
                          p_data2->_prec_addr1 = tbuf;                     /* P3V257 C */
                          p_data2->_prec_ins1  = 0;                        /* P3V257 C */
                          p_data2->_with_ins  = p_data2->_width - length;  /* P3V257 C */
                          break;

                case 'p': ivalue = (unsigned long) va_arg(arg,char *);
#if __CPU__==3                                     /* V3.0 A P3V001L */
                          if (sizeof(char *)==sizeof(long))/* V2.0 A */
                              ivalue &= 0x00ffffff;        /* V2.0 A */
#endif                                             /* V3.0 A P3V001L */
                          if (p_data2->_prec==-1) p_data2->_prec = 1;      /* P3V257 C */
                          _ltostr(ivalue,tbuf,'x',p_data2);                /* P3V257 C */
                          cp = tbuf;
                          length = strlen(cp);
                          break;

                case 'n': objp = va_arg(arg,char *);
                          *((int *)objp) = p_data1->_outch;                /* P3V257 C */
                          break;

                case '%': tbuf[0] = (char)'%';
                          cp = tbuf;
                          length = 1;
                          p_data2->_prec_addr1 = tbuf;                     /* P3V257 C */
                          p_data2->_prec_ins1  = 0;                        /* P3V257 C */
                          p_data2->_with_ins   = p_data2->_width - length; /* P3V257 C */
                          break;
                default:  _errno = ECSPEC;
                          fmtflgon(FORMERR);

            }
            if (*format!='n' && fmtflgck(FORMERR)==0){
                if (fmtflgck(LEFTADJ)==0 && p_data2->_with_ins>0){         /* P3V257 C */
                    for (;p_data2->_with_ins>0;){                          /* P3V257 C */
                        _putstr(&p_data2->_padchar,1L,p_data1);            /* P3V257 C */
                        p_data2->_with_ins--;                              /* P3V257 C */
                    }
                }
                if (p_data2->_prec_ins0==0 && p_data2->_prec_ins1==0 && p_data2->_prec_ins2==0){ /* P3V257 C */
                    _putstr(cp,length,p_data1);                            /* P3V257 C */
                }
                else{
                    i = p_data2->_prec_addr0 - cp;                         /* P3V257 C */
                    j = i;
                    if (i>0){
                        _putstr(cp,i,p_data1);                             /* P3V257 C */
                    }
                    for (; p_data2->_prec_ins0>0; p_data2->_prec_ins0--){  /* P3V257 C */
                        _putstr(&prec_char,1L,p_data1);                    /* P3V257 C */
                    }
                    i = p_data2->_prec_addr1 - p_data2->_prec_addr0;       /* P3V257 C */
                    j = j + i;
                    if (i>0){
                        _putstr(p_data2->_prec_addr0,i,p_data1);           /* P3V257 C */
                    }
                    for (; p_data2->_prec_ins1>0; p_data2->_prec_ins1--){  /* P3V257 C */
                        _putstr(&prec_char,1L,p_data1);                    /* P3V257 C */
                    }
                    _putstr(p_data2->_prec_addr1,length-j,p_data1);        /* P3V257 C */
                    for (; p_data2->_prec_ins2>0; p_data2->_prec_ins2--){  /* P3V257 C */
                        _putstr(&prec_char,1L,p_data1);                    /* P3V257 C */
                    }
                }
                if (fmtflgck(LEFTADJ)!=0 && p_data2->_with_ins>0){         /* P3V257 C */
                    for (;p_data2->_with_ins > 0;){                        /* P3V257 C */
                        _putstr(&p_data2->_padchar,1L,p_data1);            /* P3V257 C */
                        p_data2->_with_ins--;                              /* P3V257 C */
                    }
                }
            }
            format++;
        }
        else{
            p = format;
            for (;*p!='\0' && *p!='%';) p++;
            _putstr(format,(long)(p-format),p_data1);    /* P3V257 C */
            format = p;
        }
    }
    _putnull(p_data1);                                  /* P3V257(1) C */
    return((int)p_data1->_outch);                        /* P3V257 C */
}



/***********************************************************************/
/*                                                                     */
/* _ltostr subroutine :                                                */
/*                                                                     */
/***********************************************************************/
static void _ltostr(x,buf,spec,p_data2)                  /* P3V257 C */
long int x;                            /* convert value */
char     *buf;                         /* character set buffer */
int      spec;                         /* conversion spec. d/i/o/u/x/X */
_DATA2   *p_data2;                                       /* P3V257 A */
{
    unsigned long int wx;
    char              wbuf[12];        /* work area for edit */
    char              *buf_top;        /* top address of 'buf' */
    long              base;
    long              i;
    long              char_len;        /* all char length */
    long              wbuf_len;        /* numeric char len, after convert */

    buf_top = buf;
    *buf_top = (char)0;
    switch (spec){
        case 'd':
        case 'i':
        case 'u': base = 10;
                  break;

        case 'o': base = 8;
                  break;

        case 'x':
        case 'X': base = 16;
                  break;

        default :
                  break;
    }

    if (spec=='d' || spec=='i'){
        if (x>=0)
            wx = x;
        else
            wx = -x;
    }
    else
       wx = (unsigned long int)x;

    i=0;
    char_len=0;

    if (wx==0 && p_data2->_prec!=0){  /*  */ /*  */  /* P3V257 C */
        wbuf[0]=(char)'0';            /*  */
        i=1;                          /*  */
    }                                 /*  */
    else{
        for (;wx>0;i++){
            wbuf[i] = (char)(wx%base);
            if (wbuf[i]<=9) wbuf[i] += '0';
            else
              if (spec=='x') wbuf[i] += ('a'-10);
              else
                wbuf[i] += ('A'-10);
            wx = wx/base;
        }
    }

    if (fmtflgck(ONLYONE)!=0){
        switch (spec){
            case 'o': if (x!=0){
                          wbuf[i++]=(char)'0';
                      }
                      break;
            case 'x': 
            case 'X':
                      if (x!=0){          /*  */
                          *buf++ = (char)'0';
                          *buf++ = (char)spec; /* 'x' or 'X' */
                          char_len=2;
                      }
                      break;
           default  :
                      break;
        }
    }
    char_len = char_len+i;
    wbuf_len = i;

    if ((spec=='d' || spec=='i') && (p_data2->_prec!=0 || x!=0)){  /* P3V257 C */
        if (x>=0){                                                 /*  */
            if (fmtflgck(SIGNPLS)!=0){
                char_len++;
                *buf++ = (char)'+';
            }
            else{
              if (fmtflgck(SIGNSPC)!=0){
                  char_len++;
                  *buf++ = (char)' ';
              }
            }
        }
        else{
            char_len++;
            *buf++ = (char)'-';
        }
    }


    if (*buf_top=='+' || *buf_top=='-' || *buf_top==' '){
        p_data2->_prec_addr1 = buf_top + 1;                 /* P3V257 C */
    }
    else{
        if (fmtflgck(ONLYONE)!=0){
            switch (spec){
                case 'X':
                case 'x': p_data2->_prec_addr1 = buf_top+2; /* P3V257 C */
                          break;
                case 'o': p_data2->_prec_addr1 = buf_top+1; /* P3V257 C */
                          break;
                default : break;
            }
        }
        else{
            p_data2->_prec_addr1 = buf_top;                 /* P3V257 C */
        }
    }

    if (p_data2->_prec > char_len){                         /* P3V257 C */
        i = p_data2->_prec;                                 /* P3V257 C */
        p_data2->_prec_ins1 = p_data2->_prec - char_len;    /* P3V257 C */
    }
    else{
        i = char_len;
        p_data2->_prec_ins1 = 0;                            /* P3V257 C */
    }

    if ((*buf_top=='+' || *buf_top=='-' || *buf_top==' ') &&
            p_data2->_width>i && p_data2->_padchar=='0'){   /* P3V257 C */
        p_data2->_prec_ins1 += (p_data2->_width - i);       /* P3V257 C */
        p_data2->_with_ins = 0;                             /* P3V257 C */
    }
    else{
        if (p_data2->_width > i){                           /* P3V257 C */
            p_data2->_with_ins = p_data2->_width - i;       /* P3V257 C */
        }
        else{
            p_data2->_with_ins = 0;                         /* P3V257 C */
        }
    }

    for (i=wbuf_len-1; i>=0; ) *buf++ = wbuf[i--];

    *buf++ = (char)'\0';

}


#ifndef _NO_FLOAT                                      /* A P3V252-2L */
/***********************************************************************/
/*                                                                     */
/* _dtostr subroutine :                                                */
/*                                                                     */
/***********************************************************************/
static void _dtostr(x,buf,spec,p_data2)                     /* P3V257 C */
double x;
char *buf;
int  spec;
_DATA2 *p_data2;                                            /* P3V257 A */
{
    char wbuf[8];
    char sbuf[30],*sp,*buf_top;         /* decimal string */
    long exp;
    char sign;
    char w;
    long i,j,k,l,m;
    long slen;
    int  cnv_rc;

    buf_top = buf;
    sbuf[0]=(char)'0';

    if (x!=0.0){                                   /* if x is (double) 0.0 ? */
        cnv_rc=_dti(x,(INT)17,wbuf,&exp,&sign);    /* convert double  */
        if (cnv_rc!=0){
            *buf=0;
            if (p_data2->_prec > p_data2->_width)          /* P3V257 C */
            p_data2->_with_ins = p_data2->_prec;           /* P3V257 C */
            else
                p_data2->_with_ins = p_data2->_width;      /* P3V257 C */
            switch(cnv_rc){
                case  1: p_data2->_padchar='+';            /* P3V257 C */
                         break;
                case -1: p_data2->_padchar='-';            /* P3V257 C */
                         break;
                default: p_data2->_padchar='*';            /* P3V257 C */
                         break;
            }
            return;
        }
        _its(wbuf,sbuf+1,(INT)17);
    }
    else{
        sign=(char)1;
        sbuf[1]=(char)0;
    }

    for (i=1; sbuf[i]=='0'; i++);
    if (i>1){                         /* after zero delete */
        k=strlen(sbuf+i);
        exp+=(i-1);
        for (j=1; j<=k; j++,i++){
            sbuf[j]=sbuf[i];
        }
        sbuf[j]=0;
    }

    slen = strlen(sbuf+1);

    sp=sbuf+1;
    for (i=0;i<slen/2;i++){
        w = *(sp+i);
        *(sp+i)=*(sp+slen-1-i);
        *(sp+slen-1-i) = w;
    }

    if (slen==0){
        sbuf[1] = (char)'0';
        slen = 1;
        exp = 0;
    }

    if (spec=='g' || spec=='G'){
        fmtflgon(GCONVRT);
        if ((exp+slen-1)<-4 || (exp+slen-1) > p_data2->_prec)  /* P3V257 C */
          spec -= 2;
        else
          spec = (char)'f';
    }

    if (sign==1){
        w = (char)fmtflgck(SIGNPLS | SIGNSPC);
        switch (w){
            case  SIGNPLS :
                      *buf++ = (char)'+';
                      break;
            case  SIGNSPC :
                      *buf++ = (char)' ';
                      break;
            default :
                      break;

        }
    }
    else
      *buf++ = (char)'-';

    if (spec=='f'){
       if (exp>=0){
           for (i=0;i<slen;i++){
               *buf++ = sbuf[i+1];
           }

           k=0;

           p_data2->_prec_addr1 = buf;                     /* P3V257 C */
           p_data2->_prec_ins1 = exp;                      /* P3V257 C */

           if ((fmtflgck(GCONVRT) == 0 && p_data2->_prec > 0) ||  /* */ /* P3V257 C */
               (fmtflgck(ONLYONE)!=0 )){                   /*  */
               *buf++ = (char)'.';
               k++;
           }                                     /* if after zero output ? */
           if (fmtflgck(GCONVRT)==0 ||           /* (NOT %g %G) OR (%#g,%#G) case */
              (fmtflgck(GCONVRT)!=0 && fmtflgck(ONLYONE)!=0)){
               p_data2->_prec_addr2 = buf;       /* after zero put process  * P3V257 C */
               p_data2->_prec_ins2  = p_data2->_prec;                      /* P3V257 C */
               k+=p_data2->_prec;                                          /* P3V257 C */
           }

           k=k+exp+slen;
           if ((*buf_top=='+' || *buf_top=='-' || *buf_top==' ') &&
                   p_data2->_width>k && p_data2->_padchar=='0'){           /* P3V257 C */
               p_data2->_prec_addr0 = buf_top + 1;                         /* P3V257 C */
               p_data2->_prec_ins0  = p_data2->_width - k;                 /* P3V257 C */
               p_data2->_with_ins = 0;                                     /* P3V257 C */
           }
           else{
               if (p_data2->_width>k){                                     /* P3V257 C */
                   p_data2->_with_ins = p_data2->_width - k;               /* P3V257 C */
                   if (sign!=1||(sign==1&&(w==SIGNPLS||w==SIGNSPC)))
                       p_data2->_with_ins -= 1;                            /* P3V257 C */
               }
               else{
                   p_data2->_with_ins = 0;                                 /* P3V257 C */
               }
           }

       }
       else{                            /* exp<0 case */
           exp += slen;
           j = exp + p_data2->_prec;                    /* P3V257 C */
           sp=sbuf+1;
           if ((j<slen) && (j>=0)){     /* V3.0 C P3B034L:SHC-SP2-020 */
               _round(sbuf,(long)j+1);
           }
           if (exp>0){                  /* after normalize, exp>0 case */
               if (sbuf[0]=='0'){
                   i=1;
                   j=1;
               }
               else{
                   i=0;
                   j=0;
                   exp++;
                   slen++;
               }
               k=0;
               for (; exp>0; i++){
                   *buf++ = sbuf[i];
                   exp--;
                   k++;
               }
               *buf++ = (char)'.';          /*  */
               k++;                         /*  */

               for (;(i-j)<slen && p_data2->_prec>0;){     /* P3V257 C */
                   *buf++ = sbuf[i++];
                   p_data2->_prec--;                       /* P3V257 C */
                   k++;
               }                               /* if after zero output ? */
               if (fmtflgck(GCONVRT)==0 ||
                  (fmtflgck(GCONVRT)!=0 && fmtflgck(ONLYONE)!=0)){
                   k += p_data2->_prec;                    /* P3V257 C */
                   p_data2->_prec_addr1 = buf;             /* P3V257 C */
                   p_data2->_prec_ins1  = p_data2->_prec;  /* P3V257 C */
               }
               else{
                   if (*(buf-1)=='0'){
                       for (; *(buf-1)=='0'; buf--,k--);
                   }
               }
               if (fmtflgck(ONLYONE)==0 && *(buf - 1) == '.' /*  */
                                    &&                       /*  */
                 (p_data2->_prec_ins1 == 0 || fmtflgck(GCONVRT) != 0)){ /* */ /* P3V257 C */
                   buf--;                                    /*  */
                   k = k - p_data2->_prec_ins1 - 1;          /*  */   /* P3V257 C */
                   p_data2->_prec_ins1  = 0;                 /*  */   /* P3V257 C */
                   p_data2->_prec_addr1 = buf_top;           /*  */   /* P3V257 C */
               }                                             /*  */

               if ((*buf_top=='+' || *buf_top=='-' || *buf_top==' ') &&
                       p_data2->_width>k && p_data2->_padchar=='0'){  /* P3V257 C */
                   p_data2->_prec_addr0 = buf_top + 1;                /* P3V257 C */
                   p_data2->_prec_ins0  = p_data2->_width - k;        /* P3V257 C */
                   p_data2->_with_ins = 0;                            /* P3V257 C */
               }
               else{
                   if (p_data2->_width>k){                            /* P3V257 C */
                       p_data2->_with_ins = p_data2->_width - k;      /* P3V257 C */
                       if (sign!=1||(sign==1&&(w==SIGNPLS||w==SIGNSPC)))
                           p_data2->_with_ins -= 1;                   /* P3V257 C */
                   }
                   else{
                       p_data2->_with_ins = 0;                        /* P3V257 C */
                   }
               }
               if (p_data2->_prec_addr1==buf_top)                     /* P3V257 C */
                   p_data2->_prec_addr1 = p_data2->_prec_addr0;       /* P3V257 C */

           }
           else{                        /* exp<=0  case */
               if (sbuf[0]=='0'){
                   j=i=1;
               }
               else{
                   j=i=0;
                   exp++;
                   slen++;
               }

               if (exp>0){              /*  */
                   i=1;                 /*  */
                   *buf++=sbuf[0];
               }                        /*  */
               else
                   *buf++=(char)'0';

               k=1;

               *buf++ = (char)'.';          /*  */
               k++;                         /*  */
               if (exp<0){
                   p_data2->_prec_addr1=buf;                 /* P3V257 C */
                   if (p_data2->_prec > (-exp)){             /* P3V257 C */
                       p_data2->_prec_ins1 = -exp;           /* P3V257 C */
                       k+=(-exp);
                   }
                   else{
                       p_data2->_prec_ins1 = p_data2->_prec; /* P3V257 C */
                       k += p_data2->_prec;                  /* P3V257 C */
                   }
                   p_data2->_prec += exp;                    /* P3V257 C */
               }

               for (; (i-j)<slen && p_data2->_prec>0; i++){  /* P3V257 C */
                   *buf++ = sbuf[i];
                   p_data2->_prec--;                         /* P3V257 C */
                   k++;
               }                                 /* if after zero output ? */
               if (fmtflgck(GCONVRT)==0 ||
                  (fmtflgck(GCONVRT)!=0 && fmtflgck(ONLYONE)!=0)){
                   if (p_data2->_prec>0){                    /* P3V257 C */
                       p_data2->_prec_addr2=buf;             /* P3V257 C */
                       p_data2->_prec_ins2 = p_data2->_prec; /* P3V257 C */
                       k += p_data2->_prec;                  /* P3V257 C */
                   }
               }
               else{
                   if (*(buf-1)=='0'){
                       for (; *(buf-1)=='0'; buf--,k--);
                   }
               }
              if (fmtflgck(ONLYONE)==0 && *(buf - 1) == '.'  /*  */
                                    &&                       /*  */
  ((p_data2->_prec_ins1 == 0 && p_data2->_prec_ins2 == 0)|| fmtflgck(GCONVRT) != 0)){  /* P3V257 C */
                                                             /*  */
                   buf--;                                    /*  */
                   k = k - p_data2->_prec_ins1 - p_data2->_prec_ins2 - 1;   /*  */     /* P3V257 C */
                   p_data2->_prec_ins1 = p_data2->_prec_ins2 = 0;    /*  */            /* P3V257 C */
                   p_data2->_prec_addr1 = buf_top;           /*  */                    /* P3V257 C */
                   p_data2->_prec_addr2 = 0;                 /*  */                    /* P3V257 C */
               }                                             /*  */
               if ((*buf_top=='+' || *buf_top=='-' || *buf_top==' ') &&
                       p_data2->_width>k && p_data2->_padchar=='0'){  /* P3V257 C */
                   p_data2->_prec_addr0 = buf_top + 1;                /* P3V257 C */
                   p_data2->_prec_ins0  = p_data2->_width - k;        /* P3V257 C */
                   p_data2->_with_ins = 0;                            /* P3V257 C */
               }
               else{
                   if (p_data2->_width>k){                            /* P3V257 C */
                       p_data2->_with_ins = p_data2->_width - k;      /* P3V257 C */
                       if (sign!=1||(sign==1&&(w==SIGNPLS||w==SIGNSPC)))
                           p_data2->_with_ins -= 1;                   /* P3V257 C */
                   }
                   else{
                       p_data2->_with_ins = 0;                        /* P3V257 C */
                   }
               }
               if (p_data2->_prec_addr1 ==buf_top)                    /* P3V257 C */
                   p_data2->_prec_addr1 = p_data2->_prec_addr0;       /* P3V257 C */

           }
       }

    }
    else{
        if ((p_data2->_prec+1) < slen){                               /* P3V257 C */
            _round(sbuf,(long)(p_data2->_prec+2));                    /* P3V257 C */
        }
        if (sbuf[0]=='0'){
            i=1;
        }
        else{
            i=0;
            exp--;
            slen++;
        }
        exp += (slen-i);
        *buf++ = sbuf[i];
        k=1;
        *buf++ = (char)'.';          /*  */
        k++;                         /*  */
        for (j=i+1; j<=slen && p_data2->_prec>0;j++){                 /* P3V257 C */
            *buf++ = sbuf[j];
            p_data2->_prec--;                                         /* P3V257 C */
            k++;
        }
        if (fmtflgck(GCONVRT)==0 ||
           (fmtflgck(GCONVRT)!=0 && fmtflgck(ONLYONE)!=0)){
            p_data2->_prec_addr1= buf;                                /* P3V257 C */
            p_data2->_prec_ins1 = p_data2->_prec;                     /* P3V257 C */
            k += p_data2->_prec;                                      /* P3V257 C */
        }
        else{
            if (*(buf-1)=='0'){
                for (; *(buf-1)=='0'; buf--,k--);
            }
        }
               if (fmtflgck(ONLYONE)==0 && *(buf - 1) == '.' /*  */
                                    &&                       /*  */
                 (p_data2->_prec_ins1 == 0 || fmtflgck(GCONVRT) != 0)){ /*  */ /* P3V257 C */
                   buf--;                                    /*  */
                   k = k - p_data2->_prec_ins1 - 1;          /*  */            /* P3V257 C */
                   p_data2->_prec_addr1 = buf_top;           /*  */            /* P3V257 C */
                   p_data2->_prec_ins1  = 0;                 /*  */            /* P3V257 C */
               }                                             /*  */
        if (spec=='e')
            *buf++ = (char)'e';
        else
           *buf++ = (char)'E';
        k++;

        if (exp>=0)
            *buf++ = (char)'+';
        else{
            *buf++ = (char)'-';
            exp = -exp;
        }
        k++;

        if (exp>=100){
            buf += 2;
            k+=3;
        }
        else{
            *buf++ = (char)'0';
            *buf   = (char)'0';
            k+=2;
        }
        sp = buf+1;
        for (;exp>0;){
            *buf-- = (char)(exp%10+'0');
            exp = exp/10;
        }
        buf=sp;


        if ((*buf_top=='+' || *buf_top=='-' || *buf_top==' ') &&
                p_data2->_width>k && p_data2->_padchar=='0'){   /* P3V257 C */
            p_data2->_prec_addr0 = buf_top + 1;                 /* P3V257 C */
            p_data2->_prec_ins0  = p_data2->_width - k;         /* P3V257 C */
            p_data2->_with_ins = 0;                             /* P3V257 C */
        }
        else{
            if (p_data2->_width>k){                             /* P3V257 C */
                p_data2->_with_ins = p_data2->_width - k;       /* P3V257 C */
                if (sign!=1||(sign==1&&(w==SIGNPLS||w==SIGNSPC)))
                    p_data2->_with_ins -= 1;                    /* P3V257 C */
            }
            else{
                p_data2->_with_ins = 0;                         /* P3V257 C */
            }
        }
        if (p_data2->_prec_addr1 ==buf_top)                     /* P3V257 C */
            p_data2->_prec_addr1 = p_data2->_prec_addr0;        /* P3V257 C */

    }

    *buf++ = (char)'\0';
}



void _round(base,ptr)
char *base;
long ptr;
{

    if (*(base+ptr)>'4'){
        *(base+ptr)=(char)'0';
        ptr--;
        *(base+ptr)+=1;
        for (; ptr>0; ptr--){
             if (*(base+ptr)>'9'){
                 *(base+ptr)-=10;
                 *(base+ptr-1)+=1;
              }
        }
        if (*(base+1)>'9'){
            *(base+1)-=10;
            *base+=1;
        }
    }
}
#endif                                                 /* A P3V252-2L */


/***********************************************************************/
/*                                                                     */
/* _putstr subroutine :                                                */
/*                                                                     */
/***********************************************************************/
static void _putstr(buf,len,p_data1)                     /* P3V257 C */
char    *buf;
long    len;
_DATA1  *p_data1;                                        /* P3V257 A */
{
    int  i;

    if (p_data1->_outkind==1){                                     /* P3V257 C */
        memcpy((void*)p_data1->_str,(const void*)buf,(size_t)len); /* P3V257 C */
        p_data1->_str += len;                                      /* P3V257 C */
        p_data1->_outch += len;                                    /* P3V257 C */
    }
    else{
        for (i=0;i<len;i++){
            if (((*p_data1->_sofun)((int)*buf++,((FILE*)p_data1->_str)))==EOF) /* V2.0 C** P3V257(1) C */
              break;
            else
              p_data1->_outch += 1;                                /* P3V257 C */
        }
    }
}



/***********************************************************************/
/*                                                                     */
/* _putnull subroutine :                                               */
/*                                                                     */
/***********************************************************************/
static void _putnull(p_data1)                            /* P3V257 C */
_DATA1  *p_data1;                                        /* P3V257 A */
{
    if (p_data1->_outkind==1)                            /* P3V257 C */
       *p_data1->_str = (char)'\0';                      /* P3V257(1) C */
}



/***********************************************************************/
/*                                                                     */
/* _puterr subroutine :                                                */
/*                                                                     */
/***********************************************************************/
static _puterr(p_data1)                                  /* P3V257 C */
_DATA1 *p_data1;                                         /* P3V257 A */
{
    if (p_data1->_outkind==1)                            /* P3V257 C */
        return(0);
    else
      return(ferror(((FILE*)p_data1->_str)));            /* P3V257 C */
}

