stm32jy 发表于 2020-3-30 20:48

MMF103 中 printf.c 对Printf 的实现


此例程将pad字符放入输出缓冲区
static void padding( const int l_flag, params_t *par)
{
    int i;

    if (par->do_padding && l_flag && (par->len < par->num1))
      for (i = par->len; i < par->num1; i++)
            outbyte( par->pad_character);
}

stm32jy 发表于 2020-3-30 20:50

此例程按照填充和定位标志的指示将字符串移动到输出缓冲区
static void outs( charptr lp, params_t *par)
{
    /* pad on left if needed                         */
    par->len = strlen( lp);
    padding( !(par->left_flag), par);

    /* Move string to the buffer                     */
    while (*lp && (par->num2)--)
      outbyte( *lp++);

    /* Pad on right if needed                        */
    /* CR 439175 - elided next stmt. Seemed bogus.   */
    /* par->len = strlen( lp);                     */
    padding( par->left_flag, par);
}

stm32jy 发表于 2020-3-30 20:51

此例程按照填充和定位标志的指示将数字移动到输出缓冲区
static void outnum( const long n, const long base, params_t *par)
{
    charptr cp;
    int negative;
    char outbuf;
    const char digits[] = "0123456789ABCDEF";
    unsigned long num;

    /* Check if number is negative                   */
    if (base == 10 && n < 0L)
    {
      negative = 1;
      num = -(n);
    }
    else
    {
      num = (n);
      negative = 0;
    }

    /* Build number (backwards) in outbuf            */
    cp = outbuf;
    do
    {
      *cp++ = digits[(int)(num % base)];
    }
    while ((num /= base) > 0);
    if (negative)
      *cp++ = '-';
    *cp-- = 0;

    /* Move the converted number to the buffer and   */
    /* add in the padding where needed.            */
    par->len = strlen(outbuf);
    padding( !(par->left_flag), par);
    while (cp >= outbuf)
      outbyte( *cp--);
    padding( par->left_flag, par);
}

stm32jy 发表于 2020-3-30 20:52

从格式字符串中获取一个数字
static int getnum( charptr* linep)
{
    int n;
    charptr cp;

    n = 0;
    cp = *linep;
    while (isdigit(*cp))
      n = n * 10 + ((*cp++) - '0');
    *linep = cp;
    return(n);
}

stm32jy 发表于 2020-3-30 20:53

主角登场 串口printf打印函数void uart_printf( const charptr ctrl1, ...)
{

    int long_flag;
    int dot_flag;

    params_t par;

    char ch;
    va_list argp;
    charptr ctrl = ctrl1;

    va_start( argp, ctrl1);

    for ( ; *ctrl; ctrl++)
    {

      /* move format string chars to buffer until a*/
      /* format control is found.                  */
      if (*ctrl != '%')
      {
            outbyte(*ctrl);
            continue;
      }

      /* initialize all the flags for this format.   */
      dot_flag   = long_flag = par.left_flag = par.do_padding = 0;
      par.pad_character = ' ';
      par.num2 = 32767;

try_next:
      ch = *(++ctrl);

      if (isdigit(ch))
      {
            if (dot_flag)
                par.num2 = getnum(&ctrl);
            else
            {
                if (ch == '0')
                  par.pad_character = '0';

                par.num1 = getnum(&ctrl);
                par.do_padding = 1;
            }
            ctrl--;
            goto try_next;
      }

      switch (tolower(ch))
      {
            case '%':
                outbyte( '%');
                continue;

            case '-':
                par.left_flag = 1;
                break;

            case '.':
                dot_flag = 1;
                break;

            case 'l':
                long_flag = 1;
                break;

            case 'd':
                if (long_flag || ch == 'D')
                {
                  outnum( va_arg(argp, long), 10L, &par);
                  continue;
                }
                else
                {
                  outnum( va_arg(argp, int), 10L, &par);
                  continue;
                }
            case 'x':
                outnum((long)va_arg(argp, int), 16L, &par);
                continue;

            case 's':
                outs( va_arg( argp, charptr), &par);
                continue;

            case 'c':
                outbyte( va_arg( argp, int));
                continue;

            case '\\':
                switch (*ctrl)
                {
                  case 'a':
                        outbyte( 0x07);
                        break;
                  case 'h':
                        outbyte( 0x08);
                        break;
                  case 'r':
                        outbyte( 0x0D);
                        break;
                  case 'n':
                        outbyte( 0x0D);
                        outbyte( 0x0A);
                        break;
                  default:
                        outbyte( *ctrl);
                        break;
                }
                ctrl++;
                break;

            default:
                continue;
      }
      goto try_next;
    }
    va_end( argp);
}

页: [1]
查看完整版本: MMF103 中 printf.c 对Printf 的实现