/****************************************************************/
/* */
/* prf.c */
/* */
/* Abbreviated printf Function */
/* DOS-C kernel version */
/* */
/* January 10, 1993 */
/* */
/* Copyright (c) 1995 */
/* Pasquale J. Villani */
/* All Rights Reserved */
/* */
/* This file is part of DOS-C. */
/* */
/* DOS-C is free software; you can redistribute it and/or */
/* modify it under the terms of the GNU General Public License */
/* as published by the Free Software Foundation; either version */
/* 2, or (at your option) any later version. */
/* */
/* DOS-C is distributed in the hope that it will be useful, but */
/* WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */
/* the GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public */
/* License along with DOS-C; see the file COPYING. If not, */
/* write to the Free Software Foundation, 675 Mass Ave, */
/* Cambridge, MA 02139, USA. */
/****************************************************************/
#include "../../hdr/portab.h"
/* $Logfile: C:/dos-c/src/misc/prf.c_v $ */
static BYTE *prfRcsId = "$Header: C:/dos-c/src/misc/prf.c_v 1.1 01 Sep 1995 18:11:02 patv $";
/*
* $Log: C:/dos-c/src/misc/prf.c_v $
*
* Rev 1.1 01 Sep 1995 18:11:02 patv
* First GPL release.
*
* Rev 1.0 02 Jul 1995 11:04:50 patv
* Initial revision.
*/
static BYTE *charp;
#ifdef PROTO
VOID handle_char(COUNT);
VOID put_console(COUNT);
BYTE *ltob(LONG, BYTE *, COUNT);
static BYTE *itob(COUNT, BYTE *, COUNT);
COUNT do_printf(CONST BYTE *, REG BYTE **);
#else
VOID handle_char();
VOID put_console();
BYTE *ltob();
static BYTE *itob();
COUNT do_printf();
#endif
/* The following is user supplied and must match the following prototype */
#ifdef PROTO
VOID sto (COUNT);
#else
VOID sto ();
#endif
/* special console output routine */
VOID put_console(c)
COUNT c;
{
if(c == '\n')
sto('\r');
sto(c);
}
/* special handler to switch between sprintf and printf */
static VOID handle_char(c)
COUNT c;
{
if(charp == 0)
put_console(c);
else
*charp++ = c;
}
/* ltob -- convert an long integer to a string in any base (2-16) */
static BYTE *ltob(n, s, base)
LONG n;
BYTE *s;
COUNT base;
{
ULONG u;
REG BYTE *p, *q;
REG negative, c;
if (n < 0 && base == -10)
{
negative = 1;
u = -n;
}
else
{
negative = 0;
u = n;
}
if (base == -10) /* signals signed conversion */
base = 10;
p = q = s;
do
{ /* generate digits in reverse order */
*p++ = "0123456789abcdef"[u % base];
} while ((u /= base) > 0);
if (negative)
*p++ = '-';
*p = '\0'; /* terminate the string */
while (q < --p)
{ /* reverse the digits */
c = *q;
*q++ = *p;
*p = c;
}
return s;
}
/* itob -- convert an long integer to a string in any base (2-16) */
static BYTE *itob(n, s, base)
COUNT n;
BYTE *s;
COUNT base;
{
UWORD u;
REG BYTE *p, *q;
REG negative, c;
if (n < 0 && base == -10)
{
negative = 1;
u = -n;
}
else
{
negative = 0;
u = n;
}
if (base == -10) /* signals signed conversion */
base = 10;
p = q = s;
do
{ /* generate digits in reverse order */
*p++ = "0123456789abcdef"[u % base];
} while ((u /= base) > 0);
if (negative)
*p++ = '-';
*p = '\0'; /* terminate the string */
while (q < --p)
{ /* reverse the digits */
c = *q;
*q++ = *p;
*p = c;
}
return s;
}
#define NONE 0
#define LEFT 1
#define RIGHT 2
/* printf -- short version of printf to conserve space */
WORD printf(fmt, args)
CONST BYTE *fmt;
BYTE *args;
{
charp = 0;
return do_printf(fmt, &args);
}
WORD sprintf(buff, fmt, args)
BYTE *buff;
CONST BYTE *fmt;
BYTE *args;
{
WORD ret;
charp = buff;
ret = do_printf(fmt, &args);
handle_char(NULL);
return ret;
}
static COUNT do_printf(fmt, arg)
CONST BYTE *fmt;
REG BYTE **arg;
{
REG base;
BYTE s[11], *p, *ltob();
BYTE c, slen, flag, size, fill;
flag = NONE;
size = 0;
while ((c = *fmt++) != '\0')
{
if (size == 0 && flag == NONE && c != '%')
{
handle_char(c);
continue;
}
if(flag == NONE && *fmt == '0')
{
flag = RIGHT;
fill = '0';
}
switch(*fmt)
{
case '-':
flag = RIGHT;
fill = *(fmt + 1) == '0' ? '0' : ' ';
continue;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
if(flag == NONE)
flag = LEFT;
size = *fmt++ - '0';
while((c = *fmt++) != '\0')
{
switch(c)
{
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
size = size * 10 + (c - '0');
continue;
default:
--fmt;
break;
}
break;
}
break;
}
switch (c = *fmt++)
{
case 'c':
handle_char(*(COUNT *)arg++);
continue;
case 'd':
base = -10;
goto prt;
case 'o':
base = 8;
goto prt;
case 'u':
base = 10;
goto prt;
case 'x':
base = 16;
prt:
itob(*((COUNT *)arg)++, s, base);
if(flag == RIGHT || flag == LEFT)
{
for(slen = 0, p = s; *p != '\0'; p++)
++slen;
}
if(flag == RIGHT && slen < size)
{
WORD i;
for(i = size - slen; i > 0; i--)
handle_char(fill);
}
for(p = s; *p != '\0'; p++)
handle_char(*p);
if(flag == LEFT)
{
WORD i;
BYTE sp = ' ';
for(i = size - slen; i > 0; i--)
handle_char(sp);
}
size = 0;
flag = NONE;
continue;
case 'l':
switch(c = *fmt++)
{
case 'd':
base = -10;
goto lprt;
case 'o':
base = 8;
goto lprt;
case 'u':
base = 10;
goto lprt;
case 'x':
base = 16;
lprt:
ltob(*((LONG *)arg)++, s, base);
if(flag == RIGHT || flag == LEFT)
{
for(slen = 0, p = s; *p != '\0'; p++)
++slen;
}
if(flag == RIGHT && slen < size)
{
WORD i;
for(i = size - slen; i > 0; i--)
handle_char(fill);
}
for(p = s; *p != '\0'; p++)
handle_char(*p);
if(flag == LEFT)
{
WORD i;
BYTE sp = ' ';
for(i = size - slen; i > 0; i--)
handle_char(sp);
}
size = 0;
flag = NONE;
continue;
default:
handle_char(c);
}
case 's':
for(p = *arg; *p != '\0'; p++)
{
--size;
handle_char(*p);
}
for( ; size > 0; size--)
handle_char(' ');
++arg;
size = 0;
flag = NONE;
continue;
default:
handle_char(c);
continue;
}
}
return 0;
}