📄 pc_print.c
字号:
/*
* EBS - RTFS (Real Time File Manager)
*
* Copyright Peter Van Oudenaren , 1993
* All rights reserved.
* This code may not be redistributed in source or linkable object form
* without the consent of its author.
*/
/*****************************************************************************
PC_PRINTF - Mini printf for systems needing one
Summary
#include <pcdisk.h>
INT printf(format,[,argument]...)
format string description
%[flags]['0'|' '][width][.precision][typemod]type
flags if - left justify output
width width of the output
.precision may be present but is ignored
typemod l = LONG, h = Short
type c = char
d = int
i = int
x,X = Hex display of int
s = string
Additional functions:
TEXT *pc_stoa(short int num, TEXT *dest, INT base);
TEXT *pc_itoa(INT num, TEXT *dest, INT base);
TEXT *pc_ltoa(LONG num, TEXT *dest, INT base);
TEXT *pc_strjust(TEXT *to, TEXT *from, BOOL leftjust, INT width, TEXT padchart);
VOID pc_putstr(TEXT *p);
Description
Subset of printf.
NOTE:
If your environment already has printf, use it, otherwise port this code.
PORTING Considerations:
Your system is assumed to have the ANSI va_xx variable argument handling
macros. If it doesn't you'll have to get them or convert va_args() to
your own stack walking code.
All output is done via pc_putstr().The standard routine putchar() is used
to print characters. You will have to supply a putchar() routine to put
single characters to your output device.
Returns
The number of characters printed
Example:
#include <pcdisk.h>
printf("How about 3 here :%10i:\n",3);
printf("How about 3 here :%-10i:\n",3);
printf("How about X here :%c:\n",'X');
printf("How about 7L here :%4ld:\n",7L);
printf("How about joe here :%-20s:\n","JOE JACKSON");
*****************************************************************************
*/
#include "pcdisk.h"
TEXT *pc_stoa(short int num, TEXT *dest, INT base);
TEXT *pc_itoa(INT num, TEXT *dest, INT base);
TEXT *pc_ltoa(LONG num, TEXT *dest, INT base);
TEXT *pc_strjust(TEXT *to, TEXT *from, BOOL leftjust, INT width, TEXT padchar);
VOID pc_putstr(TEXT *p);
#include <stdarg.h> /*PORTME*/
#if 0
#include <stdio.h> /* PORTME- (only here for putchar) */
#endif
/* A test program if you are porting printf to your system */
/*
main()
{
char *pc_itoa();
char buff[100];
char buff2[100];
TEXT *pc_strjust();
printf("How about 3 here :%10i:\n",3);
printf("How about 3 here :%-10i:\n",3);
printf("How about X here :%c:\n",'X');
printf("How about 7L here :%4ld:\n",7L);
printf("How about 7L here :%-4ld:\n",7L);
printf("How about joe here :%30s:\n","JOE BLOW");
printf("How about joe here :%30.30s:\n","JOE BLOW");
printf("How about joe here :%-30s:\n","JOE BLOW");
printf("How about joe here :%-30.30s:\n","JOE BLOW");
printf("How about 0x456 here :%x:\n",0x456);
}
*/
/* Code starts here */
/* States */
#define PRNDOCHAR 1
#define PRNDOFMT 2
#define PRNDOFLAG 3
#define PRNDOWID 4
#define PRNDOPREC 5
#define PRNDOMOD 6
#define PRNDOTYPE 7
#define PRNDOPAD 8
/* Integer types expected */
#define PRISINT 1
#define PRISLONG 2
#define PRISSHORT 3
int printf(const char *fmt, ...) /*__fn__*/
{
va_list arg_m; /*PORTME*/
INT fmstate;
TEXT buff[20];
static TEXT boutstr[132];
BOOL leftjustify;
INT outpwidth;
INT outpmult;
INT outptype;
INT cbase;
TEXT *outstr = &boutstr[0];
TEXT c;
TEXT padchar;
va_start( arg_m, fmt); /*PORTME*/
fmstate = PRNDOCHAR; /* Start by looking for output */
while (*fmt)
{
switch (fmstate)
{
case PRNDOCHAR: /* Normal: switch states if % else just print*/
if (*fmt == '%')
fmstate = PRNDOFMT;
else
{
*outstr++ = *fmt;
fmt++;
}
break;
case PRNDOFMT: /* got a '%' reset print variable & go to flag state */
leftjustify = NO;
outpwidth = 0;
outpmult = 1;
outptype = PRISINT;
padchar = ' ';
if (*(fmt+1) == '%') /* print '%' if you get %% */
{
fmstate = PRNDOCHAR;
*outstr++ = '%';
fmt += 2;
}
else
{
fmstate = PRNDOFLAG; /* after % look for fags "-" */
fmt++;
}
break;
case PRNDOFLAG: /* Test flags and go to width state */
if (*fmt == '-')
{
leftjustify = YES;
fmt++;
}
fmstate = PRNDOPAD;
break;
case PRNDOPAD: /* Test for padding character */
if ( (*fmt == '0') || (*fmt == ' ') )
{
padchar = *fmt++;
}
fmstate = PRNDOWID;
break;
case PRNDOWID: /* In width state. convert width specifier to INT*/
if ( ('0' <= *fmt) && (*fmt <= '9') )
{
outpwidth *= outpmult;
outpmult *= 10;
outpwidth += *fmt - '0';
fmt++;
}
else /* Done with width. Go to precision state. */
fmstate = PRNDOPREC;
break;
case PRNDOPREC: /* Discard precision info and Go to MOD state*/
if ( (('0' <= *fmt) && (*fmt <= '9')) || (*fmt == '.') )
fmt++;
else
fmstate = PRNDOMOD;
break;
case PRNDOMOD: /* Look for type modifiers. And go to TYPE state */
fmstate = PRNDOTYPE;
outptype = PRISINT;
if (*fmt == 'l')
outptype = PRISLONG;
else if (*fmt == 'h')
outptype = PRISSHORT;
else
break;
fmt++;
break;
case PRNDOTYPE: /* Determine the type and display it based on the
flag:width:modier info */
fmstate = PRNDOCHAR;
switch(*fmt)
{
case 'c': /* = char */
c = va_arg(arg_m,char); /*PORTME*/
*outstr++ = c;
fmt++;
break;
default: /* INTs LONGS and SHORTS */
case 'd':
case 'i':
case 'x':
case 'X':
*outstr = '\0';
/* Hex or decimal output form */
cbase =( (*fmt == 'i') || (*fmt == 'd')) ? 10 : 16;
fmt++;
switch (outptype)
{
case PRISINT: /*PORTME*/
pc_itoa(va_arg(arg_m,int), buff,cbase);
break;
case PRISLONG: /*PORTME*/
pc_ltoa(va_arg(arg_m,long int), buff,cbase);
break;
case PRISSHORT: /*PORTME*/
pc_stoa(va_arg(arg_m,short int), buff,cbase);
break;
default:
*buff = '\0';
}
/* Now justify the the string */
pc_strjust( outstr, buff, leftjustify, outpwidth, padchar);
/* We xtoa'd into the buffer,now we have to go to the end*/
while (*outstr)
outstr++;
break;
case 's': /* = string */
fmt++;
pc_strjust( outstr,va_arg(arg_m,char *), /*PORTME*/
leftjustify, outpwidth, padchar);
while (*outstr)
outstr++;
break;
}
fmstate = PRNDOCHAR; /* Back to normal after doing a %xxx */
break;
default: /* If lost just print the format string */
fmstate = PRNDOCHAR;
*outstr++ = *fmt++;
break;
}
}
*outstr = '\0';
pc_putstr(&boutstr[0]); /*PORTME*/
return ( (INT) (outstr - &boutstr[0]) );
}
/* Short to HEX or Decimal converter */
/* Note dest buffer must hold at least 15 bytes */
TEXT *pc_stoa(short int num, TEXT *dest, INT base) /*__fn__*/
{
return (pc_ltoa( (LONG) num, dest, base));
}
/* Int to HEX or Decimal converter */
/* Note dest buffer must hold at least 15 bytes */
TEXT *pc_itoa(INT num, TEXT *dest, INT base) /*__fn__*/
{
return (pc_ltoa( (LONG) num, dest, base));
}
/* Long to HEX or Decimal converter */
/* Note dest buffer must hold at least 15 bytes */
TEXT *pc_ltoa(LONG num, TEXT *dest, INT base) /*__fn__*/
{
LONG digit;
TEXT *olddest = dest;
TEXT *p;
dest += 15;
*dest = '\0';
/* Convert num to a string going from dest[15] backwards */
/* Nasty little ItoA algorith */
do
{
digit = num % base;
*(--dest) =
(TEXT)(digit<10 ? (TEXT)(digit + '0') : (TEXT)((digit-10) + 'A'));
num = num / base;
}
while (num);
/* Now put the converted string at the beginning of the buffer */
for (p = olddest; *dest;)
*p++ = *dest++;
*p = '\0';
return (olddest);
}
/* Left or right justify a string into a buffer padding with blanks.
or padchar when right justifying
If width is zero use the width of the input string */
TEXT *pc_strjust(TEXT *to, TEXT *from, BOOL leftjust, INT width, TEXT padchar) /*__fn__*/
{
INT fromlen;
TEXT *todest;
TEXT *fromdest;
TEXT *p;
INT i;
fromlen = 0;
p = from;
while (*p++)
fromlen++;
*to = '\0';
if (!fromlen)
return (to);
if (!width)
width = fromlen;
if (leftjust)
{
pc_cppad((UTEXT *)to, (UTEXT *) from, width);
*(to + width) = '\0';
}
else /* Right justify. Filling left side with padchar */
{
/* Blank fill the string to start */
p = to;
for (i = 0; i < width; i++)
*p++ = padchar;
todest = to + width;
fromdest = (from + fromlen);
while ( (fromdest >= from) && (todest >= to) )
*todest-- = *fromdest--;
}
return (to);
}
void _screen_say(int length, int x, int y, UTINY *p);
VOID pc_putstr(TEXT *p) /*__fn__*/
{
static int ypos = 14;
_screen_say(79, 0, ypos++, p);
if (ypos == 24)
ypos = 14;
return;
#if 0
while(*p)
{
#ifdef __TURBOC__
/* Use direct conio. map \n to \r\n */
if (*p == '\n')
putch('\r');
putch(*p); /* You might have to roll your own putchar routine */
#else
putchar(*p); /* You might have to roll your own putchar routine */
#endif
p++; /* If so get rid of stdio.h above */
}
#endif
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -