📄 miniprintf.c
字号:
/*
* Copyright 2006 by Texas Instruments Incorporated.
* All rights reserved. Property of Texas Instruments Incorporated.
* Restricted rights to use, duplicate or disclose this code are
* granted through contract.
*
* @(#) TCP/IP_Network_Developers_Kit 1.91.00.08 08-22-2006 (ndk-a08)
*/
//--------------------------------------------------------------------------
// OS Demonstration Software
//--------------------------------------------------------------------------
// Printf.c
//
// Printf routines
//
// Author: Michael A. Denio
// Copyright 1999 by Texas Instruments Inc.
//-------------------------------------------------------------------------
#include <stdio.h>
#include <netmain.h>
#include <_oskern.h>
static void printstr( char *str );
#define PRINTF_LOG_SIZE 2048
#pragma DATA_SECTION(printlog, ".far:NDK_OBJMEM");
char printlog[PRINTF_LOG_SIZE];
//
// Print string to code composer
//
static void printstr( char *str )
{
static char tmpstr[160];
static int tmpidx = 0;
static int logidx = 0;
while( *str )
{
if( logidx < PRINTF_LOG_SIZE )
printlog[ logidx++ ] = *str;
tmpstr[ tmpidx++ ] = *str;
if( tmpidx == 158 || *str == '\n' )
{
if( *str == '\n' )
tmpstr[tmpidx-1] = ' ';
tmpstr[ tmpidx ] = 0;
if( tmpidx )
puts(tmpstr);
tmpidx = 0;
}
str++;
}
}
#define ARGBUF_SIZE 80
#define IBUF_SIZE 32
#define LEFT_JUSTIFIED 0x0001
#define SIGNED 0x0002
#define SPACE 0x0004
#define LEADING_ZERO 0x0008
#define PRECISION 0x0010
#define SHORT_INT 0x0020
#define LONG_INT 0x0040
#define UNSIGNED 0x0080
static int _int2str( INT32 val, char *buffer, int width, int prec,
int flag, char type )
{
char ch;
UINT32 uval,base;
int neg = 0, uns = 0;
char ibuf[IBUF_SIZE];
int idx,digit;
int oidx = 0;
// Defaul setup
base = 10;
uval = val;
// Setup for our type
switch (type)
{
case 'd':
case 'i':
if( val < 0 )
{
neg = 1;
uval = -val;
}
break;
case 'u':
uns = 1;
break;
case 'o':
base = 8;
break;
case 'x':
base = 16;
ch = 'a'-10;
break;
case 'p':
case 'X':
base = 16;
ch = 'A'-10;
break;
}
// If unsigned or base16 and val < 0, and we have a short, then trim uval
if( (base==16||uns) && val < 0 &&
( (flag&SHORT_INT) || ( !(flag&LONG_INT) && (sizeof(int)==2) )))
uval &= 0xffffl;
// Point to the end of the buffer
idx = IBUF_SIZE - 1;
// Get the digit data into our local buffer
while( uval && idx )
{
digit = (int)(uval % base);
if( digit < 10 )
ibuf[idx] = (char)(digit+'0');
else
ibuf[idx] = (char)(digit+ch);
idx--;
uval /= base;
}
// Now format it
// Pad according to precision
if( !(flag & PRECISION) )
prec = 1;
prec -= IBUF_SIZE - 1 - idx;
while( idx && prec-- > 0 )
ibuf[idx--] = '0';
// Add sign or space prefix
if( idx && neg )
ibuf[idx--] = '-';
else if( idx && flag & SIGNED )
ibuf[idx--] = '+';
else if( idx && flag & SPACE )
ibuf[idx--] = ' ';
if( flag & LEFT_JUSTIFIED )
{
// copy the string to the start of the buffer
oidx = IBUF_SIZE - 1 - idx;
mmCopy( buffer, ibuf+(idx+1), oidx );
// if larger width required, pad with spaces
while( oidx < width )
{
*(buffer + oidx) = ' ';
oidx++;
}
}
else
{
// if larger width required, pad with spaces or 0s
width -= IBUF_SIZE - 1 - idx;
if (width > 0)
{
if ((flag & LEADING_ZERO) && (!(flag & PRECISION)))
{
ch = '0';
// copy any sign prior to 0 filling
if( neg || (flag & (SIGNED | SPACE)) )
{
idx++;
*(buffer + oidx) = ibuf[idx];
oidx++;
}
}
else
ch = ' ';
while( width-- )
{
*(buffer + oidx) = ch;
oidx++;
}
}
// Copy the buffered output
mmCopy( buffer+oidx, ibuf+(idx+1), IBUF_SIZE - 1 - idx );
oidx += IBUF_SIZE - 1 - idx;
}
return( oidx );
}
static int _str2str( char *str, char *buffer, int width, int prec, int flag )
{
int oidx = 0;
int size;
// Note that "buffer" has a max size of ARGBUF_SIZE
// Bound width to buffer size
if( width > ARGBUF_SIZE )
width = ARGBUF_SIZE;
// Get STRLEN using precision
if( flag & PRECISION )
for( size=0; size<prec && *(str+size); size++ );
else
for( size=0; *(str+size); size++);
// Bound width to buffer size
if( size > ARGBUF_SIZE )
size = ARGBUF_SIZE;
// Pre-pad as required
if( !(flag & LEFT_JUSTIFIED) && (width > size) )
{
width -= size;
while( width-- )
{
*(buffer+oidx) = ' ' ;
oidx++;
}
}
// Copy in the string
mmCopy( buffer+oidx, str, size );
oidx += size;
// Post-pad as required
if( (flag & LEFT_JUSTIFIED) && (width > oidx) )
{
while( width > oidx )
{
*(buffer+oidx) = ' ' ;
oidx++;
}
}
return( oidx );
}
static int _parsearg( char *format, int *pidxp, va_list *arg, char *buffer )
{
int count = 0;
int width = 0;
int prec = 0;
int flag = 0;
int prefix = 0;
char idx = *pidxp;
va_list ap = *arg;
char cval;
// Skip past '%'
idx++;
// Parse the flags
while (!prefix)
{
switch (*(format + idx))
{
case '-':
flag |= LEFT_JUSTIFIED;
break;
case '+':
flag |= SIGNED;
break;
case ' ':
flag |= SPACE;
break;
case '0':
flag |= LEADING_ZERO;
break;
default :
prefix = 1;
break;
}
if( !prefix )
idx++;
}
// parse for a width
if( *(format+idx) == '*' )
{
width = va_arg(ap, int);
if (width < 0)
{
flag |= LEFT_JUSTIFIED;
width = -width;
}
idx++;
}
else while( *(format+idx) >= '0' && *(format+idx) <= '9' )
{
width = (width*10) + *(format+idx) - '0';
idx++;
}
// parse for a precision
if( *(format+idx) == '.' )
{
flag |= PRECISION;
idx++;
if (*(format+idx) == '*')
{
prec = va_arg(ap, int);
if (prec < 0)
{
flag &= ~PRECISION;
prec = 0;
}
idx++;
}
else while( *(format+idx) >= '0' && *(format+idx) <= '9' )
{
prec = prec * 10 + *(format+idx) - '0';
idx++;
}
}
// Parse for short/long pointer flags
if( *(format+idx) == 'h' )
{
flag |= SHORT_INT;
idx++;
}
else if( *(format+idx) == 'l' )
{
flag |= LONG_INT;
idx++;
}
/* now parse the types */
switch( *(format+idx) )
{
case 'd':
case 'i':
case 'o':
case 'u':
case 'x':
case 'X':
if( flag & LONG_INT )
count = _int2str( va_arg(ap,INT32), buffer, width, prec, flag, *(format+idx));
else
count = _int2str( va_arg(ap,int), buffer, width, prec, flag, *(format+idx));
break;
case 's':
count = _str2str( va_arg(ap,char *), buffer, width, prec, flag);
break;
case 'p':
count = _int2str( va_arg(ap,INT32), buffer, width, prec, flag, *(format+idx));
break;
case 'c':
cval = va_arg(ap, int);
*buffer = cval;
count = 1;
break;
case '%':
*buffer = '%';
count = 1;
break;
}
*pidxp = idx+1;
*arg = ap;
return count;
}
static int _printf(char *dest, char *format, va_list ap)
{
char buffer[ARGBUF_SIZE];
int idxp, idxs;
int n = 0; // number of characters written
int i;
idxp = 0;
while( n < OS_PRINTFBUFFER && *(format+idxp) )
{
idxs = idxp;
// search for '%' or NULL
while( *(format+idxp) && (*(format+idxp) != '%') )
idxp++;
// print out all characters parsed to the buffer
if( idxp > idxs )
{
if( idxs < idxp )
{
i = idxp-idxs;
if( (n+i) > OS_PRINTFBUFFER )
break;
mmCopy( dest+n, format+idxs, i );
n += i;
}
}
// Handle the '%' character
if( *(format+idxp) == '%')
{
i = _parsearg( format, &idxp, &ap, buffer );
if( (n+i) > OS_PRINTFBUFFER )
break;
mmCopy( dest+n, buffer, i );
n += i;
}
}
*(dest+n) = 0;
return( n );
}
#pragma DATA_SECTION(PrintBuffer, ".far:NDK_OBJMEM");
static char PrintBuffer[OS_PRINTFBUFFER];
int printf(const char *format, ...)
{
int count;
va_list ap;
va_start(ap, format);
count = _printf(PrintBuffer, (char *)format, ap);
va_end(ap);
printstr(PrintBuffer);
return (count);
}
int sprintf(char *s, const char *format, ...)
{
register int count;
va_list ap;
va_start(ap, format);
count = _printf(s, (char *)format, ap);
va_end(ap);
return(count);
}
int vprintf(const char *format, va_list arg)
{
register int count;
count = _printf(PrintBuffer, (char *)format, arg);
printstr(PrintBuffer);
return (count);
}
int vsprintf(char *s, const char *format, va_list arg)
{
register int count;
count = _printf(s, (char *)format, arg);
return(count);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -