?? mprintf.c
字號:
/* mprintf.c:
* A small, but useful printf.
*
* General notice:
* This code is part of a boot-monitor package developed as a generic base
* platform for embedded system designs. As such, it is likely to be
* distributed to various projects beyond the control of the original
* author. Please notify the author of any enhancements made or bugs found
* so that all may benefit from the changes. In addition, notification back
* to the author will allow the new user to pick up changes that may have
* been made by other users after this version of the code was distributed.
*
* Note1: the majority of this code was edited with 4-space tabs.
* Note2: as more and more contributions are accepted, the term "author"
* is becoming a mis-representation of credit.
*
* Original author: Ed Sutter
* Email: esutter@lucent.com
* Phone: 908-582-2351
*/
#include "Config.h"
#include <stdarg.h>
/* printf.c...
* This is my homegrown printf. It is VERY limited, but useful
* for small applications that should avoid wasting memory.
* The %s, %c, %d, %x formats are supported to some degree.
* I also added %I and %M...
* %I assumes that the argument is a long and it converts it to
* a string in IP format (a.b.c.d).
* %M assumes that the argument is a pointer to an array of 6 bytes
* and it converts it to a string in MAC format (x:y:z:a:b:c).
*
* So why don't I use varargs?...
* Yep, it sure would look nicer, and would eliminate the clumsy limit
* of 12 arguments, but so far I haven't had a problem with any of the
* CPUs I've ported to and it eliminates the headache of dealing
* with varargs vs stdargs depending on the compiler.
*
*/
#define MAXARGS 12
#define HDRSIZE 4
#define PSIZE 600 //128
#define NEGATIVE 1
#define POSITIVE 2
#define SCREENWIDTH 80
#define FRMWRI_BUFSIZE 512
#define NULL_PTR 0
#define Str_Length FRMWRI_BUFSIZE
static int ucos_vsprintf(char * str,const char *format,va_list argument);
/* printf():
* Yep, it breaks if there are more than PSIZE characters in the string
* built by sprintf.
*/
static char pbuf[PSIZE];
int myprintf( const char* fmt, ... )
{
va_list arg;
register int nc;
va_start(arg, fmt);
nc = ucos_vsprintf((char *)&pbuf, (const char *) fmt, arg);
va_end(arg);
UART0_PutData( pbuf, nc );
return nc;
}
void
comio(unsigned char output, void *number,char * strbuf)
{
/* (*((int *) number))++;*/
if (output == '\n')
*(strbuf+*((int *)number))=('\r');
*(strbuf+*((int *)number))=output;
(*((int *)number))++;
if( (*((int *)number)) == (Str_Length-1)) *((int *)number)-=1;
}
/* -------------------------------------------------------------------------- */
/* */
/* - _C_formatter - */
/* */
/* This routine forms the core and entry of the formatter. The conversion */
/* performed conforms rather well to the ANSI specification for "printf". */
/* */
/* -------------------------------------------------------------------------- */
int
_C_formatter(const char *format,
void put_one_char(unsigned char, void *,char *),
void *secret_pointer,
va_list ap, char * str)
{
char format_flag;
int precision;
int length, mask, nr_of_bits, n;
int field_width, nr_of_chars;
char flag_char, left_adjust;
unsigned long ulong;
#ifdef FLOAT_SUPPORT
double fvalue;
#endif
long num;
char *buf_pointer;
char *ptr, *hex;
char zeropad;
char buf[FRMWRI_BUFSIZE];
nr_of_chars = 0;
for (;;) /* Until full format string read */
{
while ((format_flag = *format++) != '%') /* Until '%' or '\0' */
{
if (!format_flag)
{
*(str+*((int *)secret_pointer))='\0';
return (nr_of_chars);
}
put_one_char (format_flag, secret_pointer,str);
nr_of_chars++;
} /* while () */
if (*format == '%') /* %% prints as % */
{
format++;
put_one_char('%',secret_pointer,str);
nr_of_chars++;
continue;
} /* if () */
flag_char = 0;
left_adjust = 0;
/*=====================================*/
/* check for leading -, + or ' 'flags */
/*=====================================*/
for (;;)
{
if (*format == '+' || *format == ' ')
flag_char = *format++;
else if (*format == '-')
{
left_adjust++;
format++;
}
else
break;
} /* for (;;) */
/*======================================*/
/* a '0' may follow the flag character */
/* this is the requested fill character */
/*======================================*/
if (*format == '0')
{
zeropad = 1;
format++;
}
else
zeropad = 0;
/*===================================*/
/* Optional field width (may be '*') */
/*===================================*/
if (*format == '*')
{
field_width = va_arg(ap, int);
if (field_width < 0)
{
field_width = -field_width;
left_adjust = !left_adjust;
} /* if () */
format++;
}
else
{
field_width = 0;
while (*format >= '0' && *format <= '9')
field_width = field_width * 10 + (*format++ - '0');
} /* if () */
/*=============================*/
/* Optional precision (or '*') */
/*=============================*/
if (*format=='.')
{
if (*++format == '*')
{
precision = va_arg(ap, int);
format++;
}
else
{
precision = 0;
while (*format >= '0' && *format <= '9')
precision = precision * 10 + (*format++ - '0');
} /* if () */
}
else
precision = -1;
/*======================================================*/
/* At this point, "left_adjust" is nonzero if there was */
/* a sign, "zeropad" is 1 if there was a leading zero */
/* and 0 otherwise, "field_width" and "precision" */
/* contain numbers corresponding to the digit strings */
/* before and after the decimal point, respectively, */
/* and "flag_char" is either 0 (no flag) or contains */
/* a plus or space character. If there was no decimal */
/* point, "precision" will be -1. */
/*======================================================*/
/*========================*/
/* Optional "l" modifier? */
/*========================*/
if (*format == 'l')
{
length = 1;
format++;
}
else
if (*format == 'F')
{
length = 1;
format++;
}
else
length = 0;
/*===================================================*/
/* At exit from the following switch, we will emit */
/* the characters starting at "buf_pointer" and */
/* ending at "ptr"-1 */
/*===================================================*/
switch (format_flag = *format++)
{
case 'c':
buf[0] = va_arg(ap, int);
ptr = buf_pointer = &buf[0];
if (buf[0])
ptr++;
break;
case 's':
if ((buf_pointer = va_arg(ap,char *)) == NULL_PTR)
buf_pointer = "(null pointer)";
if (precision < 0)
precision = 10000;
for (n=0; *buf_pointer++ && n < precision; n++)
;
ptr = --buf_pointer;
buf_pointer -= n;
break;
case 'o':
case 'p':
case 'X':
case 'x':
if (format_flag == 'p')
{
if (length)
ulong = (long)va_arg(ap,char *);
else
ulong = (long)va_arg(ap,char *);
}
else if (length)
ulong = va_arg(ap,unsigned long);
else
ulong = (unsigned)va_arg(ap,int);
ptr = buf_pointer = &buf[FRMWRI_BUFSIZE - 1];
hex = "0123456789ABCDEF";
if (format_flag == 'o')
{
mask = 0x7;
nr_of_bits = 3;
}
else
{
if (format_flag == 'x')
hex = "0123456789abcdef";
mask = 0xf;
nr_of_bits = 4;
} /* if () */
do
*--buf_pointer = *(hex + ((int) ulong & mask));
while ( ( ulong >>= nr_of_bits ) != 0 );
if (precision < 0) /* "precision" takes precedence */
if (zeropad)
precision = field_width;
while (precision > ptr - buf_pointer)
*--buf_pointer = '0';
break;
case 'd':
case 'i':
case 'u':
if (length)
num = va_arg(ap,long);
else
{
n = va_arg(ap,int);
if (format_flag == 'u')
num = (unsigned) n;
else
num = (long) n;
} /* if () */
if ( ( n = (format_flag != 'u' && num < 0) ) != 0 )
{
flag_char = '-';
ulong = -num;
}
else
{
n = flag_char != 0;
ulong = num;
} /* if () */
/*=======================*/
/* now convert to digits */
/*=======================*/
ptr = buf_pointer = &buf[FRMWRI_BUFSIZE - 1];
do
*--buf_pointer = (ulong % 10) + '0';
while ( (ulong /= 10) != 0 );
if (precision < 0) /* "precision" takes precedence */
if (zeropad)
precision = field_width - n;
while (precision > ptr - buf_pointer)
*--buf_pointer = '0';
break;
case 'f':
format_flag = 0;
case 'e':
case 'E':
#ifdef FLOAT_SUPPORT
if (precision < 0)
precision = 6;
buf_pointer = buf;
if ((fvalue = va_arg(ap,double)) < 0)
{
flag_char = '-';
fvalue = -fvalue;
} /* if () */
ptr = float_conversion (fvalue, precision, buf, format_flag);
#else
ptr = buf_pointer = "FLOATS? wrong formatter installed!";
while (*ptr)
ptr++;
#endif
break;
case '\0': /* Really bad place to find NUL in */
format--;
default:
/*=======================*/
/* Undefined conversion! */
/*=======================*/
ptr = buf_pointer = "???";
ptr += 4;
break;
} /* switch () */
/*===========================================================*/
/* This part emittes the formatted string to "put_one_char". */
/*===========================================================*/
if ((length = ptr - buf_pointer) > field_width)
n = 0;
else
n = field_width - length - (flag_char != 0);
/*=================================*/
/* emit any leading pad characters */
/*=================================*/
if (!left_adjust)
while (--n >= 0)
{
put_one_char(' ', secret_pointer,str);
nr_of_chars++;
} /* while () */
/*===============================*/
/* emit flag characters (if any) */
/*===============================*/
if (flag_char)
{
put_one_char(flag_char, secret_pointer,str);
nr_of_chars++;
} /* if () */
/*========================*/
/* emit the string itself */
/*========================*/
while (--length >= 0)
{
put_one_char(*buf_pointer++, secret_pointer,str);
nr_of_chars++;
} /* while () */
/*================================*/
/* emit trailing space characters */
/*================================*/
if (left_adjust)
while (--n >= 0)
{
put_one_char(' ', secret_pointer,str);
nr_of_chars++;
} /* while () */
} /* for (;;) */
*(str+*((int *)secret_pointer))='\0';
} /* _C_formatter(,,,) */
static int ucos_vsprintf(char * str,const char *format,va_list argument)
{
int number=0;
return _C_formatter(format, comio, &number, argument , str);
}
/*
int sprintf(char *str, const char *fmt, ...)
{
va_list arg;
register int nc;
va_start(arg, fmt);
nc = ucos_vsprintf((char *)&str, (const char *) fmt, arg);
va_end(arg);
return (nc);
}
*/
char isascii(char c)
{
//if((0<=c)&&(c<=127))
if (c<=127)
return c;
else
return 0;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -