Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Linux/arch/x86/boot/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 5 kB image not shown  

Quelle  printf.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0-only
/* -*- linux-c -*- ------------------------------------------------------- *
 *
 *   Copyright (C) 1991, 1992 Linus Torvalds
 *   Copyright 2007 rPath, Inc. - All Rights Reserved
 *
 * ----------------------------------------------------------------------- */


/*
 * Oh, it's a waste of space, but oh-so-yummy for debugging.  This
 * version of printf() does not include 64-bit support.  "Live with
 * it."
 *
 */


#include "boot.h"

static int skip_atoi(const char **s)
{
 int i = 0;

 while (isdigit(**s))
  i = i * 10 + *((*s)++) - '0';
 return i;
}

#define ZEROPAD 1  /* pad with zero */
#define SIGN 2  /* unsigned/signed long */
#define PLUS 4  /* show plus */
#define SPACE 8  /* space if plus */
#define LEFT 16  /* left justified */
#define SMALL 32  /* Must be 32 == 0x20 */
#define SPECIAL 64  /* 0x */

#define __do_div(n, base) ({ \
int __res; \
__res = ((unsigned long) n) % (unsigned) base; \
n = ((unsigned long) n) / (unsigned) base; \
__res; })

static char *number(char *str, long num, int base, int size, int precision,
      int type)
{
 /* we are called with base 8, 10 or 16, only, thus don't need "G..."  */
 static const char digits[16] = "0123456789ABCDEF"/* "GHIJKLMNOPQRSTUVWXYZ"; */

 char tmp[66];
 char c, sign, locase;
 int i;

 /* locase = 0 or 0x20. ORing digits or letters with 'locase'
 * produces same digits or (maybe lowercased) letters */

 locase = (type & SMALL);
 if (type & LEFT)
  type &= ~ZEROPAD;
 if (base < 2 || base > 16)
  return NULL;
 c = (type & ZEROPAD) ? '0' : ' ';
 sign = 0;
 if (type & SIGN) {
  if (num < 0) {
   sign = '-';
   num = -num;
   size--;
  } else if (type & PLUS) {
   sign = '+';
   size--;
  } else if (type & SPACE) {
   sign = ' ';
   size--;
  }
 }
 if (type & SPECIAL) {
  if (base == 16)
   size -= 2;
  else if (base == 8)
   size--;
 }
 i = 0;
 if (num == 0)
  tmp[i++] = '0';
 else
  while (num != 0)
   tmp[i++] = (digits[__do_div(num, base)] | locase);
 if (i > precision)
  precision = i;
 size -= precision;
 if (!(type & (ZEROPAD + LEFT)))
  while (size-- > 0)
   *str++ = ' ';
 if (sign)
  *str++ = sign;
 if (type & SPECIAL) {
  if (base == 8)
   *str++ = '0';
  else if (base == 16) {
   *str++ = '0';
   *str++ = ('X' | locase);
  }
 }
 if (!(type & LEFT))
  while (size-- > 0)
   *str++ = c;
 while (i < precision--)
  *str++ = '0';
 while (i-- > 0)
  *str++ = tmp[i];
 while (size-- > 0)
  *str++ = ' ';
 return str;
}

int vsprintf(char *buf, const char *fmt, va_list args)
{
 int len;
 unsigned long num;
 int i, base;
 char *str;
 const char *s;

 int flags;  /* flags to number() */

 int field_width; /* width of output field */
 int precision;  /* min. # of digits for integers; max
   number of chars for from string */

 int qualifier;  /* 'h', 'l', or 'L' for integer fields */

 for (str = buf; *fmt; ++fmt) {
  if (*fmt != '%') {
   *str++ = *fmt;
   continue;
  }

  /* process flags */
  flags = 0;
       repeat:
  ++fmt;  /* this also skips first '%' */
  switch (*fmt) {
  case '-':
   flags |= LEFT;
   goto repeat;
  case '+':
   flags |= PLUS;
   goto repeat;
  case ' ':
   flags |= SPACE;
   goto repeat;
  case '#':
   flags |= SPECIAL;
   goto repeat;
  case '0':
   flags |= ZEROPAD;
   goto repeat;
  }

  /* get field width */
  field_width = -1;
  if (isdigit(*fmt))
   field_width = skip_atoi(&fmt);
  else if (*fmt == '*') {
   ++fmt;
   /* it's the next argument */
   field_width = va_arg(args, int);
   if (field_width < 0) {
    field_width = -field_width;
    flags |= LEFT;
   }
  }

  /* get the precision */
  precision = -1;
  if (*fmt == '.') {
   ++fmt;
   if (isdigit(*fmt))
    precision = skip_atoi(&fmt);
   else if (*fmt == '*') {
    ++fmt;
    /* it's the next argument */
    precision = va_arg(args, int);
   }
   if (precision < 0)
    precision = 0;
  }

  /* get the conversion qualifier */
  qualifier = -1;
  if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L') {
   qualifier = *fmt;
   ++fmt;
  }

  /* default base */
  base = 10;

  switch (*fmt) {
  case 'c':
   if (!(flags & LEFT))
    while (--field_width > 0)
     *str++ = ' ';
   *str++ = (unsigned char)va_arg(args, int);
   while (--field_width > 0)
    *str++ = ' ';
   continue;

  case 's':
   s = va_arg(args, char *);
   len = strnlen(s, precision);

   if (!(flags & LEFT))
    while (len < field_width--)
     *str++ = ' ';
   for (i = 0; i < len; ++i)
    *str++ = *s++;
   while (len < field_width--)
    *str++ = ' ';
   continue;

  case 'p':
   if (field_width == -1) {
    field_width = 2 * sizeof(void *);
    flags |= ZEROPAD;
   }
   str = number(str,
         (unsigned long)va_arg(args, void *), 16,
         field_width, precision, flags);
   continue;

  case 'n':
   if (qualifier == 'l') {
    long *ip = va_arg(args, long *);
    *ip = (str - buf);
   } else {
    int *ip = va_arg(args, int *);
    *ip = (str - buf);
   }
   continue;

  case '%':
   *str++ = '%';
   continue;

   /* integer number formats - set up the flags and "break" */
  case 'o':
   base = 8;
   break;

  case 'x':
   flags |= SMALL;
   fallthrough;
  case 'X':
   base = 16;
   break;

  case 'd':
  case 'i':
   flags |= SIGN;
   break;

  case 'u':
   break;

  default:
   *str++ = '%';
   if (*fmt)
    *str++ = *fmt;
   else
    --fmt;
   continue;
  }
  if (qualifier == 'l')
   num = va_arg(args, unsigned long);
  else if (qualifier == 'h') {
   num = (unsigned short)va_arg(args, int);
   if (flags & SIGN)
    num = (short)num;
  } else if (flags & SIGN)
   num = va_arg(args, int);
  else
   num = va_arg(args, unsigned int);
  str = number(str, num, base, field_width, precision, flags);
 }
 *str = '\0';
 return str - buf;
}

int sprintf(char *buf, const char *fmt, ...)
{
 va_list args;
 int i;

 va_start(args, fmt);
 i = vsprintf(buf, fmt, args);
 va_end(args);
 return i;
}

int printf(const char *fmt, ...)
{
 char printf_buf[1024];
 va_list args;
 int printed;

 va_start(args, fmt);
 printed = vsprintf(printf_buf, fmt, args);
 va_end(args);

 puts(printf_buf);

 return printed;
}

Messung V0.5
C=92 H=80 G=86

¤ Dauer der Verarbeitung: 0.4 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.