Radix cross Linux Toolchains

Toolchains for all supported by Radix cross Linux devices

80 Commits   2 Branches   13 Tags
    11         kx /* Argument-processing fragment for vfprintf.
    11         kx    Copyright (C) 1991-2023 Free Software Foundation, Inc.
    11         kx    This file is part of the GNU C Library.
    11         kx 
    11         kx    The GNU C Library is free software; you can redistribute it and/or
    11         kx    modify it under the terms of the GNU Lesser General Public
    11         kx    License as published by the Free Software Foundation; either
    11         kx    version 2.1 of the License, or (at your option) any later version.
    11         kx 
    11         kx    The GNU C Library is distributed in the hope that it will be useful,
    11         kx    but WITHOUT ANY WARRANTY; without even the implied warranty of
    11         kx    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    11         kx    Lesser General Public License for more details.
    11         kx 
    11         kx    You should have received a copy of the GNU Lesser General Public
    11         kx    License along with the GNU C Library; if not, see
    11         kx    <https://www.gnu.org/licenses/>.  */
    11         kx 
    11         kx /* This file is included twice from vfprintf-internal.c, for standard
    11         kx    and GNU-style positional (%N$) arguments.  Before that,
    11         kx    process_arg_int etc. macros have to be defined to extract one
    11         kx    argument of the appropriate type, in addition to the file-specific
    11         kx    macros in vfprintf-internal.c.  */
    11         kx 
    11         kx {
    11         kx   /* Start real work.  We know about all flags and modifiers and
    11         kx      now process the wanted format specifier.  */
    11         kx LABEL (form_percent):
    11         kx   /* Write a literal "%".  */
    11         kx   Xprintf_buffer_putc (buf, L_('%'));
    11         kx   break;
    11         kx 
    11         kx LABEL (form_integer):
    11         kx   /* Signed decimal integer.  */
    11         kx   base = 10;
    11         kx 
    11         kx   if (is_longlong)
    11         kx     {
    11         kx       long long int signed_number = process_arg_long_long_int ();
    11         kx       is_negative = signed_number < 0;
    11         kx       number.longlong = is_negative ? (- signed_number) : signed_number;
    11         kx 
    11         kx       goto LABEL (longlong_number);
    11         kx     }
    11         kx   else
    11         kx     {
    11         kx       long int signed_number;
    11         kx       if (is_long_num)
    11         kx         signed_number = process_arg_long_int ();
    11         kx       else if (is_char)
    11         kx         signed_number = (signed char) process_arg_unsigned_int ();
    11         kx       else if (!is_short)
    11         kx         signed_number = process_arg_int ();
    11         kx       else
    11         kx         signed_number = (short int) process_arg_unsigned_int ();
    11         kx 
    11         kx       is_negative = signed_number < 0;
    11         kx       number.word = is_negative ? (- signed_number) : signed_number;
    11         kx 
    11         kx       goto LABEL (number);
    11         kx     }
    11         kx   /* NOTREACHED */
    11         kx 
    11         kx LABEL (form_unsigned):
    11         kx   /* Unsigned decimal integer.  */
    11         kx   base = 10;
    11         kx   goto LABEL (unsigned_number);
    11         kx   /* NOTREACHED */
    11         kx 
    11         kx LABEL (form_octal):
    11         kx   /* Unsigned octal integer.  */
    11         kx   base = 8;
    11         kx   goto LABEL (unsigned_number);
    11         kx   /* NOTREACHED */
    11         kx 
    11         kx LABEL (form_hexa):
    11         kx   /* Unsigned hexadecimal integer.  */
    11         kx   base = 16;
    11         kx   goto LABEL (unsigned_number);
    11         kx   /* NOTREACHED */
    11         kx 
    11         kx LABEL (form_binary):
    11         kx   /* Unsigned binary integer.  */
    11         kx   base = 2;
    11         kx   goto LABEL (unsigned_number);
    11         kx   /* NOTREACHED */
    11         kx 
    11         kx LABEL (unsigned_number):      /* Unsigned number of base BASE.  */
    11         kx 
    11         kx   /* ISO specifies the `+' and ` ' flags only for signed
    11         kx      conversions.  */
    11         kx   is_negative = 0;
    11         kx   showsign = 0;
    11         kx   space = 0;
    11         kx 
    11         kx   if (is_longlong)
    11         kx     {
    11         kx       number.longlong = process_arg_unsigned_long_long_int ();
    11         kx 
    11         kx       LABEL (longlong_number):
    11         kx       if (prec < 0)
    11         kx         /* Supply a default precision if none was given.  */
    11         kx         prec = 1;
    11         kx       else
    11         kx         /* We have to take care for the '0' flag.  If a precision
    11         kx            is given it must be ignored.  */
    11         kx         pad = L_(' ');
    11         kx 
    11         kx       /* If the precision is 0 and the number is 0 nothing has to
    11         kx          be written for the number, except for the 'o' format in
    11         kx          alternate form.  */
    11         kx       if (prec == 0 && number.longlong == 0)
    11         kx         {
    11         kx           string = workend;
    11         kx           if (base == 8 && alt)
    11         kx             *--string = L_('0');
    11         kx         }
    11         kx       else
    11         kx         /* Put the number in WORK.  */
    11         kx         string = _itoa (number.longlong, workend, base, spec == L_('X'));
    11         kx       /* Simplify further test for num != 0.  */
    11         kx       number.word = number.longlong != 0;
    11         kx     }
    11         kx   else
    11         kx     {
    11         kx       if (is_long_num)
    11         kx         number.word = process_arg_unsigned_long_int ();
    11         kx       else if (is_char)
    11         kx         number.word = (unsigned char) process_arg_unsigned_int ();
    11         kx       else if (!is_short)
    11         kx         number.word = process_arg_unsigned_int ();
    11         kx       else
    11         kx         number.word = (unsigned short int) process_arg_unsigned_int ();
    11         kx 
    11         kx       LABEL (number):
    11         kx       if (prec < 0)
    11         kx         /* Supply a default precision if none was given.  */
    11         kx         prec = 1;
    11         kx       else
    11         kx         /* We have to take care for the '0' flag.  If a precision
    11         kx            is given it must be ignored.  */
    11         kx         pad = L_(' ');
    11         kx 
    11         kx       /* If the precision is 0 and the number is 0 nothing has to
    11         kx          be written for the number, except for the 'o' format in
    11         kx          alternate form.  */
    11         kx       if (prec == 0 && number.word == 0)
    11         kx         {
    11         kx           string = workend;
    11         kx           if (base == 8 && alt)
    11         kx             *--string = L_('0');
    11         kx         }
    11         kx       else
    11         kx         /* Put the number in WORK.  */
    11         kx         string = _itoa_word (number.word, workend, base,
    11         kx                              spec == L_('X'));
    11         kx     }
    11         kx 
    11         kx   /* Grouping is also used for outdigits translation.  */
    11         kx   struct grouping_iterator iter;
    11         kx   bool number_slow_path = group || (use_outdigits && base == 10);
    11         kx   if (group)
    11         kx     __grouping_iterator_init (&iter, LC_NUMERIC, _NL_CURRENT_LOCALE,
    11         kx                               workend - string);
    11         kx   else if (use_outdigits && base == 10)
    11         kx     __grouping_iterator_init_none (&iter, workend - string);
    11         kx 
    11         kx   int number_length;
    11         kx #ifndef COMPILE_WPRINTF
    11         kx   if (use_outdigits && base == 10)
    11         kx     number_length = __translated_number_width (_NL_CURRENT_LOCALE,
    11         kx                                                string, workend);
    11         kx   else
    11         kx     number_length = workend - string;
    11         kx   if (group)
    11         kx     number_length += iter.separators * strlen (thousands_sep);
    11         kx #else
    11         kx   number_length = workend - string;
    11         kx   /* All wide separators have length 1.  */
    11         kx   if (group && thousands_sep != L'\0')
    11         kx     number_length += iter.separators;
    11         kx #endif
    11         kx 
    11         kx   /* The marker comes right before the number, but is not subject
    11         kx      to grouping.  */
    11         kx   bool octal_marker = (prec <= number_length && number.word != 0
    11         kx                        && alt && base == 8);
    11         kx 
    11         kx   prec = MAX (0, prec - (workend - string));
    11         kx 
    11         kx   if (!left)
    11         kx     {
    11         kx       width -= number_length + prec;
    11         kx 
    11         kx       if (number.word != 0 && alt && (base == 16 || base == 2))
    11         kx         /* Account for 0X, 0x, 0B or 0b hex or binary marker.  */
    11         kx         width -= 2;
    11         kx 
    11         kx       if (octal_marker)
    11         kx         --width;
    11         kx 
    11         kx       if (is_negative || showsign || space)
    11         kx         --width;
    11         kx 
    11         kx       if (pad == L_(' '))
    11         kx         {
    11         kx           Xprintf_buffer_pad (buf, L_(' '), width);
    11         kx           width = 0;
    11         kx         }
    11         kx 
    11         kx       if (is_negative)
    11         kx         Xprintf_buffer_putc (buf, L_('-'));
    11         kx       else if (showsign)
    11         kx         Xprintf_buffer_putc (buf, L_('+'));
    11         kx       else if (space)
    11         kx         Xprintf_buffer_putc (buf, L_(' '));
    11         kx 
    11         kx       if (number.word != 0 && alt && (base == 16 || base == 2))
    11         kx         {
    11         kx           Xprintf_buffer_putc (buf, L_('0'));
    11         kx           Xprintf_buffer_putc (buf, spec);
    11         kx         }
    11         kx 
    11         kx       width += prec;
    11         kx       Xprintf_buffer_pad (buf, L_('0'), width);
    11         kx 
    11         kx       if (octal_marker)
    11         kx         Xprintf_buffer_putc (buf, L_('0'));
    11         kx 
    11         kx       if (number_slow_path)
    11         kx         group_number (buf, &iter, string, workend, thousands_sep,
    11         kx                       use_outdigits && base == 10);
    11         kx       else
    11         kx         Xprintf_buffer_write (buf, string, workend - string);
    11         kx 
    11         kx       break;
    11         kx     }
    11         kx   else
    11         kx     {
    11         kx       if (is_negative)
    11         kx         {
    11         kx           Xprintf_buffer_putc (buf, L_('-'));
    11         kx           --width;
    11         kx         }
    11         kx       else if (showsign)
    11         kx         {
    11         kx           Xprintf_buffer_putc (buf, L_('+'));
    11         kx           --width;
    11         kx         }
    11         kx       else if (space)
    11         kx         {
    11         kx           Xprintf_buffer_putc (buf, L_(' '));
    11         kx           --width;
    11         kx         }
    11         kx 
    11         kx       if (number.word != 0 && alt && (base == 16 || base == 2))
    11         kx         {
    11         kx           Xprintf_buffer_putc (buf, L_('0'));
    11         kx           Xprintf_buffer_putc (buf, spec);
    11         kx           width -= 2;
    11         kx         }
    11         kx 
    11         kx       if (octal_marker)
    11         kx 	--width;
    11         kx 
    11         kx       width -= number_length + prec;
    11         kx 
    11         kx       Xprintf_buffer_pad (buf, L_('0'), prec);
    11         kx 
    11         kx       if (octal_marker)
    11         kx         Xprintf_buffer_putc (buf, L_('0'));
    11         kx 
    11         kx       if (number_slow_path)
    11         kx         group_number (buf, &iter, string, workend, thousands_sep,
    11         kx                       use_outdigits && base == 10);
    11         kx       else
    11         kx         Xprintf_buffer_write (buf, string, workend - string);
    11         kx 
    11         kx       Xprintf_buffer_pad (buf, L_(' '), width);
    11         kx       break;
    11         kx     }
    11         kx 
    11         kx LABEL (form_pointer):
    11         kx   /* Generic pointer.  */
    11         kx   {
    11         kx     const void *ptr = process_arg_pointer ();
    11         kx     if (ptr != NULL)
    11         kx       {
    11         kx         /* If the pointer is not NULL, write it as a %#x spec.  */
    11         kx         base = 16;
    11         kx         number.word = (unsigned long int) ptr;
    11         kx         is_negative = 0;
    11         kx         alt = 1;
    11         kx         group = 0;
    11         kx         spec = L_('x');
    11         kx         goto LABEL (number);
    11         kx       }
    11         kx     else
    11         kx       {
    11         kx         /* Write "(nil)" for a nil pointer.  */
    11         kx         string = (CHAR_T *) L_("(nil)");
    11         kx         /* Make sure the full string "(nil)" is printed.  */
    11         kx         if (prec < 5)
    11         kx           prec = 5;
    11         kx         /* This is a wide string iff compiling wprintf.  */
    11         kx         is_long = sizeof (CHAR_T) > 1;
    11         kx         goto LABEL (print_string);
    11         kx       }
    11         kx   }
    11         kx   /* NOTREACHED */
    11         kx 
    11         kx LABEL (form_number):
    11         kx   if ((mode_flags & PRINTF_FORTIFY) != 0)
    11         kx     {
    11         kx       if (! readonly_format)
    11         kx         {
    11         kx           extern int __readonly_area (const void *, size_t)
    11         kx             attribute_hidden;
    11         kx           readonly_format
    11         kx             = __readonly_area (format, ((STR_LEN (format) + 1)
    11         kx                                         * sizeof (CHAR_T)));
    11         kx         }
    11         kx       if (readonly_format < 0)
    11         kx         __libc_fatal ("*** %n in writable segment detected ***\n");
    11         kx     }
    11         kx   /* Answer the count of characters written.  */
    11         kx   void *ptrptr = process_arg_pointer ();
    11         kx   unsigned int written = Xprintf_buffer_done (buf);
    11         kx   if (is_longlong)
    11         kx     *(long long int *) ptrptr = written;
    11         kx   else if (is_long_num)
    11         kx     *(long int *) ptrptr = written;
    11         kx   else if (is_char)
    11         kx     *(char *) ptrptr = written;
    11         kx   else if (!is_short)
    11         kx     *(int *) ptrptr = written;
    11         kx   else
    11         kx     *(short int *) ptrptr = written;
    11         kx   break;
    11         kx 
    11         kx LABEL (form_strerror):
    11         kx   /* Print description of error ERRNO.  */
    11         kx   if (alt)
    11         kx     string = (CHAR_T *) __get_errname (save_errno);
    11         kx   else
    11         kx     string = (CHAR_T *) __strerror_r (save_errno, (char *) work_buffer,
    11         kx                                       WORK_BUFFER_SIZE * sizeof (CHAR_T));
    11         kx   if (string == NULL)
    11         kx     {
    11         kx       /* Print as a decimal number. */
    11         kx       base = 10;
    11         kx       is_negative = save_errno < 0;
    11         kx       number.word = save_errno;
    11         kx       if (is_negative)
    11         kx         number.word = -number.word;
    11         kx       goto LABEL (number);
    11         kx     }
    11         kx   else
    11         kx     {
    11         kx       is_long = 0;  /* This is no wide-char string.  */
    11         kx       goto LABEL (print_string);
    11         kx     }
    11         kx 
    11         kx LABEL (form_character):
    11         kx   /* Character.  */
    11         kx   if (is_long)
    11         kx     goto LABEL (form_wcharacter);
    11         kx   --width;  /* Account for the character itself.  */
    11         kx   if (!left)
    11         kx     Xprintf_buffer_pad (buf, L_(' '), width);
    11         kx #ifdef COMPILE_WPRINTF
    11         kx   __wprintf_buffer_putc (buf, __btowc ((unsigned char) /* Promoted. */
    11         kx                                        process_arg_int ()));
    11         kx #else
    11         kx   __printf_buffer_putc (buf, (unsigned char) /* Promoted.  */
    11         kx                         process_arg_int ());
    11         kx #endif
    11         kx   if (left)
    11         kx     Xprintf_buffer_pad (buf, L_(' '), width);
    11         kx   break;
    11         kx 
    11         kx LABEL (form_string):
    11         kx   {
    11         kx     size_t len;
    11         kx 
    11         kx     /* The string argument could in fact be `char *' or `wchar_t *'.
    11         kx        But this should not make a difference here.  */
    11         kx #ifdef COMPILE_WPRINTF
    11         kx     string = (CHAR_T *) process_arg_wstring ();
    11         kx #else
    11         kx     string = (CHAR_T *) process_arg_string ();
    11         kx #endif
    11         kx     /* Entry point for printing other strings.  */
    11         kx     LABEL (print_string):
    11         kx 
    11         kx     if (string == NULL)
    11         kx       {
    11         kx         /* Write "(null)" if there's space.  */
    11         kx         if (prec == -1 || prec >= (int) array_length (null) - 1)
    11         kx           {
    11         kx             string = (CHAR_T *) null;
    11         kx             len = array_length (null) - 1;
    11         kx           }
    11         kx         else
    11         kx           {
    11         kx             string = (CHAR_T *) L"";
    11         kx             len = 0;
    11         kx           }
    11         kx       }
    11         kx     else if (!is_long && spec != L_('S'))
    11         kx       {
    11         kx #ifdef COMPILE_WPRINTF
    11         kx         outstring_converted_wide_string (buf, (const char *) string,
    11         kx                                          prec, width, left);
    11         kx         /* The padding has already been written.  */
    11         kx         break;
    11         kx #else
    11         kx         if (prec != -1)
    11         kx           /* Search for the end of the string, but don't search past
    11         kx              the length (in bytes) specified by the precision.  */
    11         kx           len = __strnlen (string, prec);
    11         kx         else
    11         kx           len = strlen (string);
    11         kx #endif
    11         kx       }
    11         kx     else
    11         kx       {
    11         kx #ifdef COMPILE_WPRINTF
    11         kx         if (prec != -1)
    11         kx           /* Search for the end of the string, but don't search past
    11         kx              the length specified by the precision.  */
    11         kx           len = __wcsnlen (string, prec);
    11         kx         else
    11         kx           len = __wcslen (string);
    11         kx #else
    11         kx         outstring_converted_wide_string (buf, (const wchar_t *) string,
    11         kx                                          prec, width, left);
    11         kx         /* The padding has already been written.  */
    11         kx         break;
    11         kx #endif
    11         kx       }
    11         kx 
    11         kx     if ((width -= len) < 0)
    11         kx       {
    11         kx         Xprintf_buffer_write (buf, string, len);
    11         kx         break;
    11         kx       }
    11         kx 
    11         kx     if (!left)
    11         kx       Xprintf_buffer_pad (buf, L_(' '), width);
    11         kx     Xprintf_buffer_write (buf, string, len);
    11         kx     if (left)
    11         kx       Xprintf_buffer_pad (buf, L_(' '), width);
    11         kx   }
    11         kx   break;
    11         kx 
    11         kx #ifdef COMPILE_WPRINTF
    11         kx LABEL (form_wcharacter):
    11         kx   {
    11         kx     /* Wide character.  */
    11         kx     --width;
    11         kx     if (!left)
    11         kx       Xprintf_buffer_pad (buf, L_(' '), width);
    11         kx     Xprintf_buffer_putc (buf, process_arg_wchar_t ());
    11         kx     if (left)
    11         kx       Xprintf_buffer_pad (buf, L_(' '), width);
    11         kx   }
    11         kx   break;
    11         kx 
    11         kx #else /* !COMPILE_WPRINTF */
    11         kx LABEL (form_wcharacter):
    11         kx   {
    11         kx     /* Wide character.  */
    11         kx     char wcbuf[MB_LEN_MAX];
    11         kx     mbstate_t mbstate;
    11         kx     size_t len;
    11         kx 
    11         kx     memset (&mbstate, '\0', sizeof (mbstate_t));
    11         kx     len = __wcrtomb (wcbuf, process_arg_wchar_t (), &mbstate);
    11         kx     if (len == (size_t) -1)
    11         kx       {
    11         kx         /* Something went wrong during the conversion.  Bail out.  */
    11         kx         __printf_buffer_mark_failed (buf);
    11         kx         goto all_done;
    11         kx       }
    11         kx     width -= len;
    11         kx     if (!left)
    11         kx       Xprintf_buffer_pad (buf, L_(' '), width);
    11         kx     Xprintf_buffer_write (buf, wcbuf, len);
    11         kx     if (left)
    11         kx       Xprintf_buffer_pad (buf, L_(' '), width);
    11         kx   }
    11         kx   break;
    11         kx #endif /* !COMPILE_WPRINTF */
    11         kx }