mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-23 00:14:25 +00:00
233 lines
8.3 KiB
C
233 lines
8.3 KiB
C
/*************************************************************************
|
||
*
|
||
* _ d o p r t F u n c t i o n
|
||
* -----------------------------
|
||
* Copyright 1982 by Digital Reseacrh Inc. All rights reserved.
|
||
*
|
||
* "_doprt" handles the printing for functions "printf", "fprintf",
|
||
* and "sprintf". Each of these sets up the parameters and calls _doprt.
|
||
*
|
||
* Calling sequence:
|
||
*
|
||
* nchrs = _doprt(stream,fmt,args)
|
||
* Where:
|
||
* nchrs = number of chars output by _doprt
|
||
* stream -> destination buffer (FILE *)
|
||
* fmt -> a string specifying how "args" are to be output.
|
||
* args -> a list of arguments
|
||
*
|
||
*****************************************************************************/
|
||
#include "stdio.h"
|
||
#include "osif.h"
|
||
|
||
#define ARGWIDTH (sizeof(int)) /* width of arg to function */
|
||
#define NXTARG(ptr,isl) ((ptr)+=((isl) ? MAX(ARGWIDTH,sizeof(LONG)):ARGWIDTH))
|
||
#define IARG(ptr) ((ptr)+=ARGWIDTH) /* int arg increment */
|
||
#if CPM68K
|
||
#define FARG(ptr) ((ptr)+=sizeof(float)) /* float/double arg increment */
|
||
#else
|
||
#define FARG(ptr) ((ptr)+=sizeof(double)) /* float/double arg increment */
|
||
#endif
|
||
#define CHOOSELS(isl) ((isl) ? __prtld : __prtshort ) /* prt long or short */
|
||
#define XPUTC(a1,a2) {putc(a1,a2);nchrs++;} /* count chars output */
|
||
/****************************/
|
||
_doprt(sp,fmt,pb) /* print subroutine */
|
||
FILE *sp; /* stream buffer ptr */
|
||
BYTE *fmt; /* format string */
|
||
REG BYTE *pb; /* pointer to args */
|
||
{ /****************************/
|
||
REG BYTE c; /* format char */
|
||
BYTE **ppi; /* pointer to ptr */
|
||
WORD *pw; /* pointer to word */
|
||
BYTE padchar, /* for padding */
|
||
*s, /* string ptr for output */
|
||
buf[BUFSIZ]; /* s usually points here */
|
||
WORD width; /* for format spec */
|
||
REG WORD prec, /* precision */
|
||
len; /* total length of field */
|
||
WORD n, /* counter */
|
||
nchrs; /* number chars output */
|
||
BOOLEAN left, /* pad on left? */
|
||
longf; /* a long arg? */
|
||
MLOCAL BYTE (*fn)(); /* function holder */
|
||
GLOBAL BYTE *__prtshort(), /* for 16 bit integers */
|
||
*__prtld(); /* for 32 bit integers */
|
||
double *dblptr; /* in case we need one */
|
||
/****************************/
|
||
nchrs = 0; /* init # chars output */
|
||
if (fmt) /* make sure it's not NULL */
|
||
while (TRUE) /* examine the format string*/
|
||
{ /* */
|
||
for( len=0, s=fmt; *s && *s != '%'; ++s, ++len )
|
||
; /* grab up to EOS or '%' */
|
||
if( len > 0 ) /* did we grab anything? */
|
||
{ /* yes... */
|
||
fputn(fmt,len,sp); /* put them out */
|
||
fmt = s; /* update this pointer */
|
||
nchrs += len; /* update the counter */
|
||
} /* */
|
||
if( *fmt++ != '%' ) /* Did we stop for '%'? */
|
||
break; /* no, EOS: we're finished*/
|
||
/****************************/
|
||
left = 0; /* assume no left pad */
|
||
if ((c = *fmt++) == '-') /* left pad specified */
|
||
{ /* */
|
||
c = *fmt++; /* */
|
||
left++; /* */
|
||
} /* */
|
||
padchar = ' '; /* assume blank padding */
|
||
if (c == '0') /* zero fill specified */
|
||
{ /* */
|
||
padchar = c; /* */
|
||
c = *fmt++; /* */
|
||
} /* */
|
||
width = -1; /* assume no field spc width*/
|
||
if( c== '*' ) /* get width from args */
|
||
{ /* */
|
||
pw = pb; /* use word ptr for access */
|
||
width = *pw; /* */
|
||
IARG(pb); /* */
|
||
c = *fmt++; /* */
|
||
} /* */
|
||
else while (c >= '0' && c <= '9') /* get width from fmt */
|
||
{ /* */
|
||
if (width < 0) /* */
|
||
|
||
width = 0; /* */
|
||
width = width * 10 + (c - '0'); /* */
|
||
c = *fmt++; /* */
|
||
} /* */
|
||
prec = -1; /* assume no precision */
|
||
if (c == '.') /* get precision */
|
||
{ /* */
|
||
prec = 0; /* */
|
||
c = *fmt++; /* */
|
||
} /* */
|
||
if( c== '*' ) /* get prec from args */
|
||
{ /* */
|
||
pw = pb; /* get word pointer */
|
||
prec = *pw; /* */
|
||
IARG(pb); /* */
|
||
c = *fmt++; /* */
|
||
} /* */
|
||
else while (c >= '0' && c <= '9') /* get prec from fmt */
|
||
{ /* */
|
||
prec = prec * 10 + (c - '0'); /* */
|
||
c = *fmt++; /* */
|
||
} /* */
|
||
longf = 0; /* assume short int */
|
||
if (c == 'l' || c == 'L') /* long int specified */
|
||
{ /* */
|
||
longf++; /* */
|
||
c = *fmt++; /* */
|
||
} /****************************/
|
||
/* we now have all prelims */
|
||
/* out of the way; let's see*/
|
||
/* what we want to print */
|
||
s = buf; /* assume we'll be using buf*/
|
||
switch (c) /* */
|
||
{ /* */
|
||
/****************************/
|
||
case 'D': /* decimal signed */
|
||
longf++; /* capital letter means long*/
|
||
case 'd': /* */
|
||
fn = CHOOSELS(longf); /* */
|
||
__prtint(pb, buf, 10, TRUE, fn); /* */
|
||
NXTARG(pb,longf); /* point to next arg */
|
||
break; /* finis switch */
|
||
/****************************/
|
||
case 'U': /* decimal unsigned */
|
||
longf++; /* */
|
||
case 'u': /* */
|
||
fn = CHOOSELS(longf); /* */
|
||
__prtint(pb, buf, 10, FALSE, fn); /* */
|
||
NXTARG(pb,longf); /* */
|
||
break; /* */
|
||
/****************************/
|
||
case 'O': /* octal signed */
|
||
longf++; /* */
|
||
case 'o': /* */
|
||
fn = CHOOSELS(longf); /* */
|
||
__prtint(pb, buf, 8, FALSE, fn); /* */
|
||
NXTARG(pb,longf); /* */
|
||
break; /* */
|
||
/****************************/
|
||
case 'X': /* hexadecimal unsigned */
|
||
longf++; /* */
|
||
case 'x': /* */
|
||
fn = CHOOSELS(longf); /* */
|
||
__prtint(pb, buf, 16, FALSE, fn); /* */
|
||
NXTARG(pb,longf); /* */
|
||
break; /* */
|
||
/****************************/
|
||
case 's': /* string */
|
||
case 'S': /* */
|
||
ppi = pb; /* need to deal with ptr */
|
||
s = *ppi; /* cast to pointer */
|
||
NXTARG(pb,(sizeof(char *)==sizeof(long)));
|
||
/* TRUE if pointers are long*/
|
||
/* FALSE if not */
|
||
break; /* */
|
||
/****************************/
|
||
case 'c': /* character */
|
||
case 'C': /* */
|
||
pw = pb; /* word ptr for portability */
|
||
buf[0] = (*pw & 0377); /* assume chars passed as */
|
||
buf[1] = NULL; /* ints */
|
||
IARG(pb); /* */
|
||
break; /* */
|
||
/****************************/
|
||
/****************************/
|
||
case 'E': /* E format */
|
||
case 'e': /* */
|
||
_petoa(pb, buf, prec, c);/* Do the conversion */
|
||
FARG(pb); /* Bump to next arg */
|
||
prec = -1; /* Avoid truncation */
|
||
break; /* Next */
|
||
/****************************/
|
||
case 'F': /* F format floating */
|
||
case 'f': /* */
|
||
_pftoa(pb, buf, prec, c);/* do the conversion */
|
||
FARG(pb); /* Bump to next arg */
|
||
prec = -1; /* Avoid truncation */
|
||
break; /* */
|
||
/****************************/
|
||
case 'G': /* G format floating */
|
||
case 'g': /* */
|
||
_pgtoa(pb, buf, prec, c);/* do the conversion */
|
||
FARG(pb); /* Bump to next arg */
|
||
prec = -1; /* Avoid truncation */
|
||
break; /* */
|
||
/****************************/
|
||
/****************************/
|
||
default: /* just print the character */
|
||
XPUTC(c,sp); /* */
|
||
continue; /* */
|
||
} /****************************/
|
||
len = strlen(s); /* how long is the output? */
|
||
if (prec < len && prec >= 0) /* cut off if user says so */
|
||
len = prec; /* */
|
||
n = width - len; /* how much extra room? */
|
||
if (!left) /* if left not specified */
|
||
{ /* */
|
||
if (padchar == '0' && *s == '-') /* check for neg */
|
||
{ /* */
|
||
len--; /* output minus if leading 0*/
|
||
XPUTC(*s++,sp); /* */
|
||
|
||
} /* */
|
||
while (n-- > 0) /* now pad on left */
|
||
XPUTC(padchar,sp); /* */
|
||
} /* */
|
||
fputn(s,len,sp); /* put buffered n chars */
|
||
nchrs += len; /* assume they got there */
|
||
while (n-- > 0) /* anything remain, then pad*/
|
||
XPUTC(padchar,sp); /* */
|
||
} /* */
|
||
return(nchrs); /* report on # chars output */
|
||
} /****************************/
|
||
put */
|
||
} /****************************/
|
||
put */
|
||
} /****************************/
|