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

📄 printf.c

📁 ADAM2 sources (modified by Oleg)
💻 C
📖 第 1 页 / 共 2 页
字号:
            if ((negative) || (flag & (SIGNED | SPACE)))
               *ptr2++ = *ptr++;
         }
         else
            ch = ' ';
         while (width--)
            *ptr2++ = ch;
      }

      /* copy the string from the end of the buffer */
      while(ptr < bufend)
         *ptr2++ = *ptr++;
   }
   return ptr2 - buffer;
}

static int _str2str
(
    char *str,
    char *buffer,
    int  width,
    int  precision,
    int  flag
)
{
   int  ndigits;
   int  i;
   char *ptr = buffer;
   char *ptr2 = str;
                                  
   if (flag & PRECISION)
      for (i = 0; (i < precision) && (*ptr2++ != '\0'); i++);
   else
      for (i = 0; *ptr2++ != '\0'; i++);
   ndigits = i;
   
   /* left-padding if required */
   if ((!(flag & LEFT_JUSTIFIED)) && (width > ndigits))
   {
      width -= ndigits;
      while (width--)
         *ptr++ = ' ';
   }

   /* now copy the string */
   for (i = 0, ptr2 = str; i < ndigits; i++)
      *ptr++ = *ptr2++;

   /* right-padding if required */
   if ((flag & LEFT_JUSTIFIED) && (width > ndigits))
   {
      width -= ndigits;
      while (width--)
         *ptr++ = ' ';
   }
   return ptr - buffer;
}

static int _parsearg
(
char    **fmt,
va_list *arg,
char    *buffer,
int     n
)
{
   int     count          = 0;
   int     width          = 0;
   int     precision      = 0;
   int     flag           = 0;
   int     parsed_flags   = FALSE;
   char    *ptr   = *fmt;
   va_list ap  = *arg;
   char    ch,*cp;

   /* skip % */
   ptr++;

   /* parse the flags */
   while (!parsed_flags)
   {
      switch (*ptr++)
      {
         case '-' : flag |= LEFT_JUSTIFIED;     break;
         case '+' : flag |= SIGNED;             break;
         case ' ' : flag |= SPACE;              break;
         case '#' : flag |= ALTERNATE;          break;
         case '0' : flag |= LEADING_ZERO;       break;
         default  : parsed_flags = TRUE; --ptr; break;
      }
   }

   /* parse for a width */
   if (*ptr == '*')
   {
      width = va_arg(ap, int);
      if (width < 0)
      {
         flag |= LEFT_JUSTIFIED;
         width = -width;
      }
      ptr++;
   }
   else
      while (isdigit(*ptr))
         width = width * 10 + (*ptr++ - '0');

   /* parse for a precision */
   if (*ptr == '.')
   {
      flag |= PRECISION;
      ptr++;
      if (*ptr == '*')
      {
         precision = va_arg(ap, int);
         if (precision < 0)
         {
            /* for a negative precision, treat it as if it were missing */
            flag &= ~PRECISION;
            precision = 0;
         }
         ptr++;
      }
      else
         while (isdigit(*ptr))
            precision = precision * 10 + (*ptr++ - '0');
   }

   /* parse for short/long pointer flags */
   switch (*ptr++)
   {
      case 'h' : flag |= SHORT_INT;    break;
      case 'l' : flag |= LONG_INT;     break;
      case 'L' : flag |= LONG_DOUBLE;  break;
      default  : --ptr;                break;
   }

   /* now parse the types */
   switch (*ptr)
   {
      case 'd':   
      case 'i':
      case 'o':   
      case 'u':
      case 'x':
      case 'X':
                  count = _int2str((flag & LONG_INT) ? va_arg(ap, long) : va_arg(ap, int),
                                   buffer, width, precision, flag, *ptr);
                  break;
      case 'c':   ch = va_arg(ap, int);
                  flag |= PRECISION;
                  count = _str2str(&ch, buffer, width, 1, flag);
                  break;
      case 's':   cp=va_arg(ap, char *);
                  if (cp)
                    count = _str2str(cp, buffer, width, precision, flag);
                   else
                    count = _str2str("NULL", buffer, width, precision, flag);
                  break;
      case 'p':
                  count = _int2str(va_arg(ap, int), buffer, width, precision, flag, *ptr);
                  break;
      case 'n':
                  *(va_arg(ap, int *)) = n;
                  break;
      case '%':
                  *buffer = '%';
                  count = 1;
                  break;   
   }
   *fmt = ++ptr;
   *arg = ap;
   return count;
}

int _printf(char *dest, char *format, va_list ap)
{
   char buffer[MAX_STRING_SIZE];
   char *tstr;
   char *save,*fmt = format;
   int  n = 0; /* number of characters written */
   int  i,count;

   while (*fmt != '\0')
   {
      /* search for % or \0 */
      save = fmt;
      while ((*fmt != '\0') && (*fmt != '%'))
         fmt++;
      /* print out all characters parsed to the buffer */
      if ((count = (fmt - save)))
      {
         n += count;
         tstr = save;
         for(i=0; i<count; i++)
             *dest++ = *tstr++;
      }
      if (*fmt == '%')
      {
         i = _parsearg(&fmt, &ap, buffer, n);
         n += i;
         tstr = buffer;
         while( i-- )
             *dest++ = *tstr++;
      }
   }
   *dest++ = 0;
   return n;
}

int sys_printf(const char *format, ...)
{
   int     count;
   va_list ap;
   char    buffer[MAX_STRING_SIZE];

   va_start(ap, format);
   count = _printf(buffer, (char *)format, ap);
   va_end(ap);
   (*_PrintfOutStr)(buffer);
   return (count);
}

int sys_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 sys_vprintf(const char *format, va_list arg)
{
   register int count;
   char     buffer[MAX_STRING_SIZE];

   count = _printf(buffer, (char *)format, arg);
 (*_PrintfOutStr)(buffer);
   return(count);
}

int sys_vsprintf(char *s, const char *format, va_list arg)
{
   register int count;

   count = _printf(s, (char *)format, arg);
   return(count);
}
void PrintfRedirect(void (*afunction)(char *))
{
  _PrintfOutStr=afunction;
}

void PrintfRestore()
{
  _PrintfOutStr=SioOutStr;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -