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

📄 printf_large.c

📁 这项工程将让您把自己的MP3播放器平台
💻 C
📖 第 1 页 / 共 2 页
字号:
  unsigned char  length;
  char           c;

#ifdef SDCC_STACK_AUTO
  #define output_char   pfn
  #define p             pvoid
#else
  output_char = pfn;
  p = pvoid;
#endif

  // reset output chars
  charsOutputted=0;

#ifdef SDCC_ds390
  if (format==0) {
    format=NULL_STRING;
  }
#endif

  while( c=*format++ )
  {
    if ( c=='%' )
    {
      left_justify    = 0;
      zero_padding    = 0;
      prefix_sign     = 0;
      prefix_space    = 0;
      signed_argument = 0;
      radix           = 0;
      char_argument   = 0;
      long_argument   = 0;
      float_argument  = 0;
      width           = 0;
      decimals        = -1;

get_conversion_spec:

      c = *format++;

      if (c=='%') {
        output_char(c, p);
        charsOutputted++;
        continue;
      }

      if (isdigit(c)) {
        if (decimals==-1) {
          width = 10*width + (c - '0');
          if (width == 0) {
            /* first character of width is a zero */
            zero_padding = 1;
          }
        } else {
          decimals = 10*decimals + (c-'0');
        }
        goto get_conversion_spec;
      }

      if (c=='.') {
        if (decimals=-1) decimals=0;
        else
          ; // duplicate, ignore
        goto get_conversion_spec;
      }

      lower_case = islower(c);
      if (lower_case)
      {
        c = toupper(c);
      }

      switch( c )
      {
      case '-':
        left_justify = 1;
        goto get_conversion_spec;
      case '+':
        prefix_sign = 1;
        goto get_conversion_spec;
      case ' ':
        prefix_space = 1;
        goto get_conversion_spec;
      case 'B':
        char_argument = 1;
        goto get_conversion_spec;
      case 'L':
        long_argument = 1;
        goto get_conversion_spec;

      case 'C':
        output_char( va_arg(ap,int), p );
        charsOutputted++;
        break;

      case 'S':
        PTR = va_arg(ap,ptr_t);

#ifdef SDCC_ds390
        if (PTR==0) {
          PTR=NULL_STRING;
          length=NULL_STRING_LENGTH;
        } else {
          length = strlen(PTR);
        }
#else
        length = strlen(PTR);
#endif
        if ( ( !left_justify ) && (length < width) )
        {
          width -= length;
          while( width-- != 0 )
          {
            output_char( ' ', p );
            charsOutputted++;
          }
        }

        while ( *PTR && (decimals != 0))
          {
            output_char( *PTR++, p );
            charsOutputted++;
	    if (decimals != -1) --decimals;
          }
	
        if ( left_justify && (length < width))
        {
          width -= length;
          while( width-- != 0 )
          {
            output_char( ' ', p );
            charsOutputted++;
          }
        }
        break;

      case 'P':
        PTR = va_arg(ap,ptr_t);

#ifdef SDCC_ds390
        output_char(memory_id[(value.byte[3] > 3) ? 4 : value.byte[3]], p );
        output_char(':', p);
        output_char('0', p);
        output_char('x', p);
        OUTPUT_2DIGITS( value.byte[2] );
        OUTPUT_2DIGITS( value.byte[1] );
        OUTPUT_2DIGITS( value.byte[0] );
        charsOutputted += 10;
#else
        output_char( memory_id[(value.byte[2] > 3) ? 4 : value.byte[2]], p );
        output_char(':', p);
        output_char('0', p);
        output_char('x', p);
        if ((value.byte[2] != 0x00 /* DSEG */) &&
            (value.byte[2] != 0x03 /* SSEG */))
        {
          OUTPUT_2DIGITS( value.byte[1] );
          charsOutputted += 2;
        }
        OUTPUT_2DIGITS( value.byte[0] );
        charsOutputted += 6;
#endif
        break;

      case 'D':
      case 'I':
        signed_argument = 1;
        radix = 10;
        break;

      case 'O':
        radix = 8;
        break;

      case 'U':
        radix = 10;
        break;

      case 'X':
        radix = 16;
        break;

      case 'F':
        float_argument=1;
        break;

      default:
        // nothing special, just output the character
        output_char( c, p );
        charsOutputted++;
        break;
      }

      if (float_argument) {
        value.f=va_arg(ap,float);
#if !USE_FLOATS
        PTR="<NO FLOAT>";
        while (c=*PTR++)
        {
          output_char (c, p);
          charsOutputted++;
        }
        // treat as long hex
        //radix=16;
        //long_argument=1;
        //zero_padding=1;
        //width=8;
#else
        // ignore b and l conversion spec for now
        charsOutputted += OUTPUT_FLOAT(value.f, width, decimals, left_justify,
                                     zero_padding, prefix_sign, prefix_space);
#endif
      } else if (radix != 0)
      {
        // Apperently we have to output an integral type
        // with radix "radix"
        unsigned char store[6];
        unsigned char _AUTOMEM *pstore = &store[5];

        // store value in byte[0] (LSB) ... byte[3] (MSB)
        if (char_argument)
        {
          value.l = va_arg(ap,char);
          if (!signed_argument)
          {
            value.l &= 0xFF;
          }
        }
        else if (long_argument)
        {
          value.l = va_arg(ap,long);
        }
        else // must be int
        {
          value.l = va_arg(ap,int);
          if (!signed_argument)
          {
            value.l &= 0xFFFF;
          }
        }

        if ( signed_argument )
        {
          if (value.l < 0)
            value.l = -value.l;
          else
            signed_argument = 0;
        }

        length=0;
        lsd = 1;

        do {
          value.byte[4] = 0;
#if defined SDCC_STACK_AUTO
          calculate_digit(&value, radix);
#else
          calculate_digit(radix);
#endif
          if (!lsd)
          {
            *pstore = (value.byte[4] << 4) | (value.byte[4] >> 4) | *pstore;
            pstore--;
          }
          else
          {
            *pstore = value.byte[4];
          }
          length++;
          lsd = !lsd;
        } while( value.ul );

        if (width == 0)
        {
          // default width. We set it to 1 to output
          // at least one character in case the value itself
          // is zero (i.e. length==0)
          width=1;
        }

        /* prepend spaces if needed */
        if (!zero_padding && !left_justify)
        {
          while ( width > (unsigned char) (length+1) )
          {
            output_char( ' ', p );
            charsOutputted++;
            width--;
          }
        }

        if (signed_argument) // this now means the original value was negative
        {
          output_char( '-', p );
          charsOutputted++;
          // adjust width to compensate for this character
          width--;
        }
        else if (length != 0)
        {
          // value > 0
          if (prefix_sign)
          {
            output_char( '+', p );
            charsOutputted++;
            // adjust width to compensate for this character
            width--;
          }
          else if (prefix_space)
          {
            output_char( ' ', p );
            charsOutputted++;
            // adjust width to compensate for this character
            width--;
          }
        }

        /* prepend zeroes/spaces if needed */
        if (!left_justify)
          while ( width-- > length )
          {
            output_char( zero_padding ? '0' : ' ', p );
            charsOutputted++;
          }
        else
        {
          /* spaces are appended after the digits */
          if (width > length)
            width -= length;
          else
            width = 0;
        }

        /* output the digits */
        while( length-- )
        {
          lsd = !lsd;
          if (!lsd)
          {
            pstore++;
            value.byte[4] = *pstore >> 4;
          }
          else
          {
            value.byte[4] = *pstore & 0x0F;
          }
#ifdef SDCC_STACK_AUTO
          output_digit( value.byte[4], lower_case, output_char, p );
#else
          output_digit( value.byte[4] );
#endif
          charsOutputted++;
        }
        if (left_justify)
          while (width-- > 0)
          {
            output_char(' ', p);
            charsOutputted++;
          }
      }
    }
    else
    {
      // nothing special, just output the character
      output_char( c, p );
      charsOutputted++;
    }
  }

  return charsOutputted;
}

/****************************************************************************/

⌨️ 快捷键说明

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