⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mprintf.c

📁 基于ARM7处理器的中断与串口在ucos下切换的演示程序
💻 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 + -