From f8463f1275382c5de0e6154ff4e1190ba79404f6 Mon Sep 17 00:00:00 2001 From: Kevin Day Date: Sat, 26 Feb 2022 10:50:26 -0600 Subject: [PATCH] Security: The va_list has undefined behavior when passed into functions. When the va_list is started using va_start(), the va_arg() must be called within the same function. This is a design problem with how va_list and its respective functions are implemented. The man pages directly document that passing an already started va_list to a function and then calling va_arg() is undefined. The va_list, being a macro, might also be a pointer. This makes passing it as a pointer (or with "const") risky. Due to the mentioned undefined states and risks, this is considered and treated as a security issue. Move the va_XXX() logic into a single function. This unfortunately means some functions have to be expanded out into the code and deleted. The code now, unfortunately, has more nested as a result of having to add more loops within the same function. The va_copy() macro is used and so the ap list state is no longer changed outside of the function. --- level_1/fl_print/c/print.c | 37 +- level_1/fl_print/c/print.h | 10 +- level_1/fl_print/c/private-print.c | 1930 ++++++++++++++++++------------------ level_1/fl_print/c/private-print.h | 26 +- level_2/fll_print/c/print.c | 6 +- level_2/fll_print/c/print.h | 4 +- 6 files changed, 1002 insertions(+), 1011 deletions(-) diff --git a/level_1/fl_print/c/print.c b/level_1/fl_print/c/print.c index 42c5032..e0ceb90 100644 --- a/level_1/fl_print/c/print.c +++ b/level_1/fl_print/c/print.c @@ -18,20 +18,7 @@ extern "C" { va_start(ap, stream); - for (f_string_t current = string; *current; ++current) { - - if (*current == f_string_ascii_percent_s.string[0]) { - ++current; - - current = private_fl_print_format_convert(current, stream, &ap, &status); - if (F_status_is_error(status)) break; - } - else { - if (!fputc_unlocked(*current, stream)) { - break; - } - } - } // for + private_fl_print_format_convert(string, stream, ap, &status); va_end(ap); @@ -42,10 +29,9 @@ extern "C" { #endif // _di_fl_print_format_ #ifndef _di_fl_print_format_convert_ - f_string_t fl_print_format_convert(const f_string_t string, FILE * const stream, va_list * const ap, f_status_t * const status) { + f_string_t fl_print_format_convert(const f_string_t string, FILE * const stream, va_list ap, f_status_t * const status) { #ifndef _di_level_1_parameter_checking_ if (!stream) return 0; - if (!ap) return 0; #endif // _di_level_1_parameter_checking_ return private_fl_print_format_convert(string, stream, ap, status); @@ -53,30 +39,15 @@ extern "C" { #endif // _di_fl_print_format_convert_ #ifndef _di_fl_print_string_va_ - f_status_t fl_print_string_va(const f_string_t string, FILE * const stream, va_list * const ap) { + f_status_t fl_print_string_va(const f_string_t string, FILE * const stream, va_list ap) { #ifndef _di_level_1_parameter_checking_ if (!string) return F_status_set_error(F_parameter); if (!stream) return F_status_set_error(F_parameter); - if (!ap) return F_status_set_error(F_parameter); #endif // _di_level_1_parameter_checking_ f_status_t status = F_none; - for (f_string_t current = string; *current; ++current) { - - if (*current == f_string_ascii_percent_s.string[0]) { - ++current; - - current = private_fl_print_format_convert(current, stream, ap, &status); - if (F_status_is_error(status)) break; - } - else { - if (!fputc_unlocked(*current, stream)) { - break; - } - } - } // for - + private_fl_print_format_convert(string, stream, ap, &status); if (F_status_is_error(status)) return status; return F_none; diff --git a/level_1/fl_print/c/print.h b/level_1/fl_print/c/print.h index 4107a08..ad6a0b9 100644 --- a/level_1/fl_print/c/print.h +++ b/level_1/fl_print/c/print.h @@ -209,8 +209,9 @@ extern "C" { * @see fprintf() * @see fputc_unlocked() * @see snprintf() - * @see va_start() + * @see va_copy() * @see va_end() + * @see va_start() * * @see f_conversion_number_signed_print() * @see f_conversion_number_unsigned_print() @@ -280,7 +281,7 @@ extern "C" { * @see f_print_terminated() */ #ifndef _di_fl_print_format_convert_ - extern f_string_t fl_print_format_convert(const f_string_t string, FILE * const stream, va_list * const ap, f_status_t * const status); + extern f_string_t fl_print_format_convert(const f_string_t string, FILE * const stream, va_list ap, f_status_t * const status); #endif // _di_fl_print_format_convert_ /** @@ -315,8 +316,9 @@ extern "C" { * Errors (with error bit) from: f_print_terminated(). * * @see fputc_unlocked() - * @see va_start() + * @see va_copy() * @see va_end() + * @see va_start() * * @see f_conversion_number_signed_print() * @see f_conversion_number_unsigned_print() @@ -328,7 +330,7 @@ extern "C" { * @see fl_print_format() */ #ifndef _di_fl_print_string_va_ - extern f_status_t fl_print_string_va(const f_string_t string, FILE * const stream, va_list * const ap); + extern f_status_t fl_print_string_va(const f_string_t string, FILE * const stream, va_list ap); #endif // _di_fl_print_string_va_ /** diff --git a/level_1/fl_print/c/private-print.c b/level_1/fl_print/c/private-print.c index d5b50da..e98cc4e 100644 --- a/level_1/fl_print/c/private-print.c +++ b/level_1/fl_print/c/private-print.c @@ -6,1157 +6,1199 @@ extern "C" { #endif #if !defined(_di_fl_print_format_) || !defined(_di_fl_print_format_convert_) - f_string_t private_fl_print_format_convert(f_string_t string, FILE * const stream, va_list * const ap, f_status_t * const status) { + f_string_t private_fl_print_format_convert(f_string_t string, FILE * const stream, va_list ap, f_status_t * const status) { - const f_string_t start = string; - - // An unpaired '%' character must not be at the end of the string. - if (!*string) { - *status = F_status_set_error(F_eos); - - return string; - } - - *status = F_none; - - uint8_t base = 10; - uint32_t flag = 0; - uint8_t type = 0; - - unsigned int width = 1; - unsigned int precision = 1; + // Due to the technical design of the va_list, this must be created, copied, and ended within this function. + va_list apl; + va_copy(apl, ap); for (; *string; ++string) { - if (*string < 0x2c) { - if (*string == f_string_ascii_space_s.string[0]) { - flag |= F_print_format_flag_sign_pad_d; + if (*string == f_string_ascii_percent_s.string[0]) { + ++string; - continue; - } - else if (*string == f_string_ascii_exclamation_s.string[0]) { - base = 2; + const f_string_t start = string; - continue; - } - else if (*string == f_string_ascii_pound_s.string[0]) { - flag |= F_print_format_flag_convert_d; + // An unpaired '%' character must not be at the end of the string. + if (!*string) { + *status = F_status_set_error(F_eos); - continue; - } - else if (*string == f_string_ascii_dollar_s.string[0]) { + va_end(apl); - // If followed immediately by a '$' this is ignored. - // Use '%$' to separate, such as '%l%$l' would allow for '0l' to be printed where '%ll' would interpret the 'l', resulting in a long long. return string; } - else if (*string == f_string_ascii_percent_s.string[0]) { - // The first percent found represents a literal '%' to be printed, otherwise return as invalid. - if (string == start) { - if (fwrite_unlocked(f_string_ascii_percent_s.string, 1, f_string_ascii_percent_s.used, stream) < f_string_ascii_percent_s.used) { - *status = F_status_set_error(F_output); - } - } - else { - *status = F_status_set_error(F_valid_not); - } + *status = F_none; - return string; - } - else if (*string == f_string_ascii_ampersand_s.string[0]) { - base = 12; + uint8_t base = 10; + uint32_t flag = 0; + uint8_t type = 0; - continue; - } - else if (*string == f_string_ascii_asterisk_s.string[0]) { - flag |= F_print_format_flag_width_d | F_print_format_flag_width_value_d; - continue; - } - else if (*string == f_string_ascii_plus_s.string[0]) { - flag |= F_print_format_flag_sign_always_d; + unsigned int width = 1; + unsigned int precision = 1; - continue; - } - else { - *status = F_status_set_error(F_valid_not); + for (; *string; ++string) { - return string; - } - } - else if (*string < 0x41) { - if (*string == f_string_ascii_minus_s.string[0]) { - flag |= F_print_format_flag_align_left_d; - - continue; - } - else if (*string == f_string_ascii_period_s.string[0]) { - if (!*(string + 1)) { - *status = F_status_set_error(F_eos); - - return string; - } - - ++string; - - if (*string == f_string_ascii_asterisk_s.string[0]) { - flag |= F_print_format_flag_precision_d | F_print_format_flag_precision_value_d; - } - else if (*string < 0x30 || *string > 0x39) { - *status = F_status_set_error(F_valid_not); - - return string; - } - else { - string = private_fl_print_convert_number(string, ap, &precision, status); - if (F_status_is_error(*status)) return string; - - flag |= F_print_format_flag_precision_d; - } - - continue; - } - else if (*string == f_string_ascii_slash_forward_s.string[0]) { - flag |= F_print_format_flag_range_d; - - continue; - } - else if (*string > 0x2f && *string < 0x3a) { - if (!(flag & F_print_format_flag_width_d)) { - if (*string == f_string_ascii_0_s.string[0]) { - flag |= F_print_format_flag_zeros_leading_d; + if (*string < 0x2c) { + if (*string == f_string_ascii_space_s.string[0]) { + flag |= F_print_format_flag_sign_pad_d; continue; } + else if (*string == f_string_ascii_exclamation_s.string[0]) { + base = 2; - flag |= F_print_format_flag_width_d; - - string = private_fl_print_convert_number(string, ap, &width, status); - if (F_status_is_error(*status)) return string; - - continue; - } - else { - *status = F_status_set_error(F_valid_not); - - return string; - } - } - else if (*string == f_string_ascii_colon_s.string[0]) { - flag |= F_print_format_flag_ignore_range_d; - - continue; - } - else if (*string == f_string_ascii_colon_semi_s.string[0]) { - flag |= F_print_format_flag_ignore_index_d; - - continue; - } - else if (*string == f_string_ascii_equal_s.string[0]) { - flag |= F_print_format_flag_trim_d; - - continue; - } - else if (*string == f_string_ascii_sign_at_s.string[0]) { - base = 8; - - continue; - } - else { - *status = F_status_set_error(F_valid_not); - - return string; - } - } - else if (*string < 0x56) { - if (*string == f_string_ascii_C_s.string[0]) { - char value[1] = { (char) va_arg(*ap, int) }; - - *status = f_print_safely(value, 1, stream); + continue; + } + else if (*string == f_string_ascii_pound_s.string[0]) { + flag |= F_print_format_flag_convert_d; - return string; - } - else if (*string == f_string_ascii_D_s.string[0]) { - type = f_print_format_type_double_32_e; - flag |= F_print_format_flag_uppercase_d; + continue; + } + else if (*string == f_string_ascii_dollar_s.string[0]) { - if (*(string + 1)) { - if (*(string + 1) == f_string_ascii_L_s.string[0]) { - type = f_print_format_type_double_64_e; + // If followed immediately by a '$' this is ignored. + // Use '%$' to separate, such as '%l%$l' would allow for '0l' to be printed where '%ll' would interpret the 'l', resulting in a long long. + break; + } + else if (*string == f_string_ascii_percent_s.string[0]) { - if (*(string + 2) == f_string_ascii_e_s.string[0]) { - flag |= F_print_format_flag_exponent_d; - string += 2; - } - else if (*(string + 2) == f_string_ascii_E_s.string[0]) { - flag |= F_print_format_flag_exponent_d | F_print_format_flag_exponent_upper_d; - string += 2; - } - else if (*(string + 2) == f_string_ascii_g_s.string[0]) { - flag |= F_print_format_flag_exponent_either_d; - string += 2; - } - else if (*(string + 2) == f_string_ascii_G_s.string[0]) { - flag |= F_print_format_flag_exponent_either_d | F_print_format_flag_exponent_upper_d; - string += 2; + // The first percent found represents a literal '%' to be printed, otherwise return as invalid. + if (string == start) { + if (fwrite_unlocked(f_string_ascii_percent_s.string, 1, f_string_ascii_percent_s.used, stream) < f_string_ascii_percent_s.used) { + *status = F_status_set_error(F_output); + } } else { - ++string; + *status = F_status_set_error(F_valid_not); } + + break; } - else if (*(string + 1) == f_string_ascii_e_s.string[0]) { - flag |= F_print_format_flag_exponent_d; - ++string; - } - else if (*(string + 1) == f_string_ascii_E_s.string[0]) { - flag |= F_print_format_flag_exponent_d | F_print_format_flag_exponent_upper_d; - ++string; - } - else if (*(string + 1) == f_string_ascii_g_s.string[0]) { - flag |= F_print_format_flag_exponent_either_d; - ++string; - } - else if (*(string + 1) == f_string_ascii_G_s.string[0]) { - flag |= F_print_format_flag_exponent_either_d | F_print_format_flag_exponent_upper_d; - ++string; - } - } - } - else if (*string == f_string_ascii_I_s.string[0]) { - type = f_print_format_type_signed_32_e; - flag |= F_print_format_flag_uppercase_d; + else if (*string == f_string_ascii_ampersand_s.string[0]) { + base = 12; - if (*(string + 1) == f_string_ascii_I_s.string[0]) { - if (*(string + 2) == f_string_ascii_I_s.string[0]) { - type = f_print_format_type_signed_8_e; - string += 2; + continue; } - else { - type = f_print_format_type_signed_16_e; - ++string; + else if (*string == f_string_ascii_asterisk_s.string[0]) { + flag |= F_print_format_flag_width_d | F_print_format_flag_width_value_d; + continue; } - } - else if (*(string + 1) == f_string_ascii_L_s.string[0]) { - if (*(string + 2) == f_string_ascii_L_s.string[0]) { - type = f_print_format_type_signed_128_e; - string += 2; + else if (*string == f_string_ascii_plus_s.string[0]) { + flag |= F_print_format_flag_sign_always_d; + + continue; } else { - type = f_print_format_type_signed_64_e; - ++string; + *status = F_status_set_error(F_valid_not); + + break; } } - else if (*(string + 1) == f_string_ascii_N_s.string[0]) { - type = f_print_format_type_signed_number_e; - flag |= F_print_format_flag_uppercase_d; - ++string; - } - } - else if (*string == f_string_ascii_Q_s.string[0]) { - const f_string_static_t value = va_arg(*ap, f_string_static_t); - - if (flag & F_print_format_flag_range_d) { - const f_string_range_t partial = va_arg(*ap, f_string_range_t); - - if (flag & F_print_format_flag_ignore_index_d) { - const f_array_lengths_t except_at = va_arg(*ap, f_array_lengths_t); - f_string_ranges_t except_in = f_string_ranges_t_initialize; - - if (flag & F_print_format_flag_ignore_range_d) { - except_in = va_arg(*ap, f_string_ranges_t); - } + else if (*string < 0x41) { + if (*string == f_string_ascii_minus_s.string[0]) { + flag |= F_print_format_flag_align_left_d; - if (partial.start > partial.stop) { - *status = F_data_not; + continue; + } + else if (*string == f_string_ascii_period_s.string[0]) { + if (!*(string + 1)) { + *status = F_status_set_error(F_eos); - return string; + break; } - f_array_length_t length = (partial.stop - partial.start) + 1; + ++string; - if (length + partial.start > value.used) { - length = value.used - partial.start; + if (*string == f_string_ascii_asterisk_s.string[0]) { + flag |= F_print_format_flag_precision_d | F_print_format_flag_precision_value_d; } + else if (*string < 0x30 || *string > 0x39) { + *status = F_status_set_error(F_valid_not); - if (flag & F_print_format_flag_trim_d) { - *status = private_fl_print_trim_except_in_safely(value.string, partial.start, length, except_at, except_in, stream); + break; } else { - *status = f_print_except_in_safely(value.string, partial.start, length, except_at, except_in, stream); - } - } - else if (flag & F_print_format_flag_ignore_range_d) { - const f_array_lengths_t except_at = f_array_lengths_t_initialize; - const f_string_ranges_t except_in = va_arg(*ap, f_string_ranges_t); + for (precision = 0; *string; ++string) { - if (partial.start > partial.stop) { - *status = F_data_not; + if (*string > 0x2f && *string < 0x3a) { + precision *= 10; + precision += 0xf & *string; + } + else if (*string == f_string_ascii_asterisk_s.string[0]) { + precision = va_arg(apl, unsigned int); - return string; - } + break; + } + else { - f_array_length_t length = (partial.stop - partial.start) + 1; + // Do not leave string on the non-digit and non-asterisk character. + --string; - if (length + partial.start > value.used) { - length = value.used - partial.start; - } + break; + } + } // for - if (flag & F_print_format_flag_trim_d) { - *status = private_fl_print_trim_except_in_safely(value.string, partial.start, length, except_at, except_in, stream); - } - else { - *status = f_print_except_in_safely(value.string, partial.start, length, except_at, except_in, stream); - } - } - else { - const f_array_lengths_t except_at = f_array_lengths_t_initialize; - const f_string_ranges_t except_in = f_string_ranges_t_initialize; - - if (partial.start > partial.stop) { - *status = F_data_not; - - return string; - } + // Do not leave string on the terminating NULL. + if (!string) { + --string; + } - f_array_length_t length = (partial.stop - partial.start) + 1; + if (F_status_is_error(*status)) break; - if (length + partial.start > value.used) { - length = value.used - partial.start; + flag |= F_print_format_flag_precision_d; } - if (flag & F_print_format_flag_trim_d) { - *status = private_fl_print_trim_safely(value.string + partial.start, length, stream); - } - else { - *status = f_print_safely(value.string + partial.start, length, stream); - } - } - } - else if (flag & F_print_format_flag_ignore_index_d) { - const f_array_lengths_t except_at = va_arg(*ap, f_array_lengths_t); - f_string_ranges_t except_in = f_string_ranges_t_initialize; - - if (flag & F_print_format_flag_ignore_range_d) { - except_in = va_arg(*ap, f_string_ranges_t); + continue; } + else if (*string == f_string_ascii_slash_forward_s.string[0]) { + flag |= F_print_format_flag_range_d; - if (flag & F_print_format_flag_trim_d) { - *status = private_fl_print_trim_except_in_safely(value.string, 0, value.used, except_at, except_in, stream); - } - else { - *status = f_print_except_in_dynamic_safely(value, except_at, except_in, stream); + continue; } - } - else if (flag & F_print_format_flag_ignore_range_d) { - const f_array_lengths_t except_at = f_array_lengths_t_initialize; - const f_string_ranges_t except_in = va_arg(*ap, f_string_ranges_t); + else if (*string > 0x2f && *string < 0x3a) { + if (!(flag & F_print_format_flag_width_d)) { + if (*string == f_string_ascii_0_s.string[0]) { + flag |= F_print_format_flag_zeros_leading_d; - if (flag & F_print_format_flag_trim_d) { - *status = private_fl_print_trim_except_in_safely(value.string, 0, value.used, except_at, except_in, stream); - } - else { - *status = f_print_except_in_dynamic_safely(value, except_at, except_in, stream); - } - } - else { - if (flag & F_print_format_flag_trim_d) { - *status = private_fl_print_trim_safely(value.string, value.used, stream); - } - else { - *status = f_print_dynamic_safely(value, stream); - } - } + continue; + } - return string; - } - else if (*string == f_string_ascii_R_s.string[0]) { - const f_string_static_t value = va_arg(*ap, f_string_static_t); + flag |= F_print_format_flag_width_d; - if (flag & F_print_format_flag_range_d) { - const f_string_range_t partial = va_arg(*ap, f_string_range_t); + { + for (width = 0; *string; ++string) { - if (flag & F_print_format_flag_ignore_index_d) { - const f_array_lengths_t except_at = va_arg(*ap, f_array_lengths_t); - f_string_ranges_t except_in = f_string_ranges_t_initialize; + if (*string > 0x2f && *string < 0x3a) { + width *= 10; + width += 0xf & *string; + } + else if (*string == f_string_ascii_asterisk_s.string[0]) { + width = va_arg(apl, unsigned int); - if (flag & F_print_format_flag_ignore_range_d) { - except_in = va_arg(*ap, f_string_ranges_t); - } + break; + } + else { - if (partial.start > partial.stop) { - *status = F_data_not; + // Do not leave string on the non-digit and non-asterisk character. + --string; - return string; - } + break; + } + } // for - f_array_length_t length = (partial.stop - partial.start) + 1; + // Do not leave string on the terminating NULL. + if (!string) { + --string; + } + } - if (length + partial.start > value.used) { - length = value.used - partial.start; - } + if (F_status_is_error(*status)) break; - if (flag & F_print_format_flag_trim_d) { - *status = private_fl_print_trim_except_in_raw_safely(value.string, partial.start, length, except_at, except_in, stream); + continue; } else { - *status = f_print_except_in_raw_safely(value.string, partial.start, length, except_at, except_in, stream); + *status = F_status_set_error(F_valid_not); + + break; } } - else if (flag & F_print_format_flag_ignore_range_d) { - const f_array_lengths_t except_at = f_array_lengths_t_initialize; - const f_string_ranges_t except_in = va_arg(*ap, f_string_ranges_t); + else if (*string == f_string_ascii_colon_s.string[0]) { + flag |= F_print_format_flag_ignore_range_d; - if (partial.start > partial.stop) { - *status = F_data_not; + continue; + } + else if (*string == f_string_ascii_colon_semi_s.string[0]) { + flag |= F_print_format_flag_ignore_index_d; - return string; - } + continue; + } + else if (*string == f_string_ascii_equal_s.string[0]) { + flag |= F_print_format_flag_trim_d; - f_array_length_t length = (partial.stop - partial.start) + 1; + continue; + } + else if (*string == f_string_ascii_sign_at_s.string[0]) { + base = 8; - if (length + partial.start > value.used) { - length = value.used - partial.start; + continue; + } + else { + *status = F_status_set_error(F_valid_not); + + break; + } + } + else if (*string < 0x56) { + if (*string == f_string_ascii_C_s.string[0]) { + char value[1] = { (char) va_arg(apl, int) }; + + *status = f_print_safely(value, 1, stream); + + break; + } + else if (*string == f_string_ascii_D_s.string[0]) { + type = f_print_format_type_double_32_e; + flag |= F_print_format_flag_uppercase_d; + + if (*(string + 1)) { + if (*(string + 1) == f_string_ascii_L_s.string[0]) { + type = f_print_format_type_double_64_e; + + if (*(string + 2) == f_string_ascii_e_s.string[0]) { + flag |= F_print_format_flag_exponent_d; + string += 2; + } + else if (*(string + 2) == f_string_ascii_E_s.string[0]) { + flag |= F_print_format_flag_exponent_d | F_print_format_flag_exponent_upper_d; + string += 2; + } + else if (*(string + 2) == f_string_ascii_g_s.string[0]) { + flag |= F_print_format_flag_exponent_either_d; + string += 2; + } + else if (*(string + 2) == f_string_ascii_G_s.string[0]) { + flag |= F_print_format_flag_exponent_either_d | F_print_format_flag_exponent_upper_d; + string += 2; + } + else { + ++string; + } + } + else if (*(string + 1) == f_string_ascii_e_s.string[0]) { + flag |= F_print_format_flag_exponent_d; + ++string; + } + else if (*(string + 1) == f_string_ascii_E_s.string[0]) { + flag |= F_print_format_flag_exponent_d | F_print_format_flag_exponent_upper_d; + ++string; + } + else if (*(string + 1) == f_string_ascii_g_s.string[0]) { + flag |= F_print_format_flag_exponent_either_d; + ++string; + } + else if (*(string + 1) == f_string_ascii_G_s.string[0]) { + flag |= F_print_format_flag_exponent_either_d | F_print_format_flag_exponent_upper_d; + ++string; + } } - - if (flag & F_print_format_flag_trim_d) { - *status = private_fl_print_trim_except_in_raw_safely(value.string, partial.start, length, except_at, except_in, stream); + } + else if (*string == f_string_ascii_I_s.string[0]) { + type = f_print_format_type_signed_32_e; + flag |= F_print_format_flag_uppercase_d; + + if (*(string + 1) == f_string_ascii_I_s.string[0]) { + if (*(string + 2) == f_string_ascii_I_s.string[0]) { + type = f_print_format_type_signed_8_e; + string += 2; + } + else { + type = f_print_format_type_signed_16_e; + ++string; + } } - else { - *status = f_print_except_in_raw_safely(value.string, partial.start, length, except_at, except_in, stream); + else if (*(string + 1) == f_string_ascii_L_s.string[0]) { + if (*(string + 2) == f_string_ascii_L_s.string[0]) { + type = f_print_format_type_signed_128_e; + string += 2; + } + else { + type = f_print_format_type_signed_64_e; + ++string; + } + } + else if (*(string + 1) == f_string_ascii_N_s.string[0]) { + type = f_print_format_type_signed_number_e; + flag |= F_print_format_flag_uppercase_d; + ++string; } } - else { - const f_array_lengths_t except_at = f_array_lengths_t_initialize; - const f_string_ranges_t except_in = f_string_ranges_t_initialize; - - if (partial.start > partial.stop) { - *status = F_data_not; - - return string; + else if (*string == f_string_ascii_Q_s.string[0]) { + const f_string_static_t value = va_arg(apl, f_string_static_t); + + if (flag & F_print_format_flag_range_d) { + const f_string_range_t partial = va_arg(apl, f_string_range_t); + + if (flag & F_print_format_flag_ignore_index_d) { + const f_array_lengths_t except_at = va_arg(apl, f_array_lengths_t); + f_string_ranges_t except_in = f_string_ranges_t_initialize; + + if (flag & F_print_format_flag_ignore_range_d) { + except_in = va_arg(apl, f_string_ranges_t); + } + + if (partial.start > partial.stop) { + *status = F_data_not; + + break; + } + + f_array_length_t length = (partial.stop - partial.start) + 1; + + if (length + partial.start > value.used) { + length = value.used - partial.start; + } + + if (flag & F_print_format_flag_trim_d) { + *status = private_fl_print_trim_except_in_safely(value.string, partial.start, length, except_at, except_in, stream); + } + else { + *status = f_print_except_in_safely(value.string, partial.start, length, except_at, except_in, stream); + } + } + else if (flag & F_print_format_flag_ignore_range_d) { + const f_array_lengths_t except_at = f_array_lengths_t_initialize; + const f_string_ranges_t except_in = va_arg(apl, f_string_ranges_t); + + if (partial.start > partial.stop) { + *status = F_data_not; + + break; + } + + f_array_length_t length = (partial.stop - partial.start) + 1; + + if (length + partial.start > value.used) { + length = value.used - partial.start; + } + + if (flag & F_print_format_flag_trim_d) { + *status = private_fl_print_trim_except_in_safely(value.string, partial.start, length, except_at, except_in, stream); + } + else { + *status = f_print_except_in_safely(value.string, partial.start, length, except_at, except_in, stream); + } + } + else { + const f_array_lengths_t except_at = f_array_lengths_t_initialize; + const f_string_ranges_t except_in = f_string_ranges_t_initialize; + + if (partial.start > partial.stop) { + *status = F_data_not; + + break; + } + + f_array_length_t length = (partial.stop - partial.start) + 1; + + if (length + partial.start > value.used) { + length = value.used - partial.start; + } + + if (flag & F_print_format_flag_trim_d) { + *status = private_fl_print_trim_safely(value.string + partial.start, length, stream); + } + else { + *status = f_print_safely(value.string + partial.start, length, stream); + } + } } - - f_array_length_t length = (partial.stop - partial.start) + 1; - - if (length + partial.start > value.used) { - length = value.used - partial.start; + else if (flag & F_print_format_flag_ignore_index_d) { + const f_array_lengths_t except_at = va_arg(apl, f_array_lengths_t); + f_string_ranges_t except_in = f_string_ranges_t_initialize; + + if (flag & F_print_format_flag_ignore_range_d) { + except_in = va_arg(apl, f_string_ranges_t); + } + + if (flag & F_print_format_flag_trim_d) { + *status = private_fl_print_trim_except_in_safely(value.string, 0, value.used, except_at, except_in, stream); + } + else { + *status = f_print_except_in_dynamic_safely(value, except_at, except_in, stream); + } } - - if (flag & F_print_format_flag_trim_d) { - *status = private_fl_print_trim_raw_safely(value.string + partial.start, length, stream); + else if (flag & F_print_format_flag_ignore_range_d) { + const f_array_lengths_t except_at = f_array_lengths_t_initialize; + const f_string_ranges_t except_in = va_arg(apl, f_string_ranges_t); + + if (flag & F_print_format_flag_trim_d) { + *status = private_fl_print_trim_except_in_safely(value.string, 0, value.used, except_at, except_in, stream); + } + else { + *status = f_print_except_in_dynamic_safely(value, except_at, except_in, stream); + } } else { - *status = f_print_raw_safely(value.string + partial.start, length, stream); + if (flag & F_print_format_flag_trim_d) { + *status = private_fl_print_trim_safely(value.string, value.used, stream); + } + else { + *status = f_print_dynamic_safely(value, stream); + } } - } - } - else if (flag & F_print_format_flag_ignore_index_d) { - const f_array_lengths_t except_at = va_arg(*ap, f_array_lengths_t); - f_string_ranges_t except_in = f_string_ranges_t_initialize; - if (flag & F_print_format_flag_ignore_range_d) { - except_in = va_arg(*ap, f_string_ranges_t); + break; } + else if (*string == f_string_ascii_R_s.string[0]) { + const f_string_static_t value = va_arg(apl, f_string_static_t); - if (flag & F_print_format_flag_trim_d) { - *status = private_fl_print_trim_except_in_raw_safely(value.string, 0, value.used, except_at, except_in, stream); - } - else { - *status = f_print_except_in_dynamic_raw_safely(value, except_at, except_in, stream); - } - } - else if (flag & F_print_format_flag_ignore_range_d) { - const f_array_lengths_t except_at = f_array_lengths_t_initialize; - const f_string_ranges_t except_in = va_arg(*ap, f_string_ranges_t); + if (flag & F_print_format_flag_range_d) { + const f_string_range_t partial = va_arg(apl, f_string_range_t); - if (flag & F_print_format_flag_trim_d) { - *status = private_fl_print_trim_except_in_raw_safely(value.string, 0, value.used, except_at, except_in, stream); - } - else { - *status = f_print_except_in_dynamic_raw_safely(value, except_at, except_in, stream); - } - } - else { - if (flag & F_print_format_flag_trim_d) { - *status = private_fl_print_trim_raw_safely(value.string, value.used, stream); - } - else { - *status = f_print_dynamic_raw_safely(value, stream); - } - } + if (flag & F_print_format_flag_ignore_index_d) { + const f_array_lengths_t except_at = va_arg(apl, f_array_lengths_t); + f_string_ranges_t except_in = f_string_ranges_t_initialize; - return string; - } - else if (*string == f_string_ascii_S_s.string[0]) { - const f_string_t value = va_arg(*ap, f_string_t); + if (flag & F_print_format_flag_ignore_range_d) { + except_in = va_arg(apl, f_string_ranges_t); + } - *status = f_print_safely_terminated(value, stream); + if (partial.start > partial.stop) { + *status = F_data_not; - return string; - } - else if (*string == f_string_ascii_U_s.string[0]) { - type = f_print_format_type_unsigned_32_e; - flag |= F_print_format_flag_uppercase_d; + break; + } - if (*(string + 1) == f_string_ascii_I_s.string[0]) { - if (*(string + 2) == f_string_ascii_I_s.string[0]) { - type = f_print_format_type_unsigned_8_e; - string += 2; - } - else { - type = f_print_format_type_unsigned_16_e; - ++string; - } - } - else if (*(string + 1) == f_string_ascii_L_s.string[0]) { - if (*(string + 2) == f_string_ascii_L_s.string[0]) { - type = f_print_format_type_unsigned_128_e; - string += 2; - } - else { - type = f_print_format_type_unsigned_64_e; - ++string; - } - } - else if (*(string + 1) == f_string_ascii_N_s.string[0]) { - type = f_print_format_type_unsigned_number_e; - ++string; - } - } - else { - *status = F_status_set_error(F_valid_not); + f_array_length_t length = (partial.stop - partial.start) + 1; - return string; - } - } - else if (*string < 0x60) { - if (*string == f_string_ascii_Z_s.string[0]) { - type = f_print_format_type_size_e; - flag |= F_print_format_flag_uppercase_d; - } - else if (*string == f_string_ascii_bracket_open_s.string[0]) { - const f_color_set_t value = va_arg(*ap, f_color_set_t); + if (length + partial.start > value.used) { + length = value.used - partial.start; + } - if (value.before) { - *status = f_print_dynamic_raw(*value.before, stream); - } + if (flag & F_print_format_flag_trim_d) { + *status = private_fl_print_trim_except_in_raw_safely(value.string, partial.start, length, except_at, except_in, stream); + } + else { + *status = f_print_except_in_raw_safely(value.string, partial.start, length, except_at, except_in, stream); + } + } + else if (flag & F_print_format_flag_ignore_range_d) { + const f_array_lengths_t except_at = f_array_lengths_t_initialize; + const f_string_ranges_t except_in = va_arg(apl, f_string_ranges_t); - return string; - } - else if (*string == f_string_ascii_bracket_close_s.string[0]) { - const f_color_set_t value = va_arg(*ap, f_color_set_t); + if (partial.start > partial.stop) { + *status = F_data_not; - if (value.after) { - *status = f_print_dynamic_raw(*value.after, stream); - } + break; + } - return string; - } - else if (*string == f_string_ascii_caret_s.string[0]) { - base = 10; + f_array_length_t length = (partial.stop - partial.start) + 1; - continue; - } - else if (*string == f_string_ascii_underscore_s.string[0]) { - base = 16; + if (length + partial.start > value.used) { + length = value.used - partial.start; + } - continue; - } - else { - *status = F_status_set_error(F_valid_not); + if (flag & F_print_format_flag_trim_d) { + *status = private_fl_print_trim_except_in_raw_safely(value.string, partial.start, length, except_at, except_in, stream); + } + else { + *status = f_print_except_in_raw_safely(value.string, partial.start, length, except_at, except_in, stream); + } + } + else { + const f_array_lengths_t except_at = f_array_lengths_t_initialize; + const f_string_ranges_t except_in = f_string_ranges_t_initialize; - return string; - } - } - else if (*string < 0x72) { - if (*string == f_string_ascii_c_s.string[0]) { - const char value = (char) va_arg(*ap, uint32_t); + if (partial.start > partial.stop) { + *status = F_data_not; - if (!fputc_unlocked(value, stream)) { - *status = F_status_set_error(F_output); - } + break; + } - return string; - } - else if (*string == f_string_ascii_d_s.string[0]) { - type = f_print_format_type_double_32_e; + f_array_length_t length = (partial.stop - partial.start) + 1; - if (*(string + 1)) { - if (*(string + 1) == f_string_ascii_L_s.string[0]) { - type = f_print_format_type_double_64_e; + if (length + partial.start > value.used) { + length = value.used - partial.start; + } - if (*(string + 2) == f_string_ascii_e_s.string[0]) { - flag |= F_print_format_flag_exponent_d; - string += 2; + if (flag & F_print_format_flag_trim_d) { + *status = private_fl_print_trim_raw_safely(value.string + partial.start, length, stream); + } + else { + *status = f_print_raw_safely(value.string + partial.start, length, stream); + } + } } - else if (*(string + 2) == f_string_ascii_E_s.string[0]) { - flag |= F_print_format_flag_exponent_d | F_print_format_flag_exponent_upper_d; - string += 2; + else if (flag & F_print_format_flag_ignore_index_d) { + const f_array_lengths_t except_at = va_arg(apl, f_array_lengths_t); + f_string_ranges_t except_in = f_string_ranges_t_initialize; + + if (flag & F_print_format_flag_ignore_range_d) { + except_in = va_arg(apl, f_string_ranges_t); + } + + if (flag & F_print_format_flag_trim_d) { + *status = private_fl_print_trim_except_in_raw_safely(value.string, 0, value.used, except_at, except_in, stream); + } + else { + *status = f_print_except_in_dynamic_raw_safely(value, except_at, except_in, stream); + } } - else if (*(string + 2) == f_string_ascii_g_s.string[0]) { - flag |= F_print_format_flag_exponent_either_d; - string += 2; - } - else if (*(string + 2) == f_string_ascii_G_s.string[0]) { - flag |= F_print_format_flag_exponent_either_d | F_print_format_flag_exponent_upper_d; - string += 2; + else if (flag & F_print_format_flag_ignore_range_d) { + const f_array_lengths_t except_at = f_array_lengths_t_initialize; + const f_string_ranges_t except_in = va_arg(apl, f_string_ranges_t); + + if (flag & F_print_format_flag_trim_d) { + *status = private_fl_print_trim_except_in_raw_safely(value.string, 0, value.used, except_at, except_in, stream); + } + else { + *status = f_print_except_in_dynamic_raw_safely(value, except_at, except_in, stream); + } } else { - ++string; + if (flag & F_print_format_flag_trim_d) { + *status = private_fl_print_trim_raw_safely(value.string, value.used, stream); + } + else { + *status = f_print_dynamic_raw_safely(value, stream); + } } - } - else if (*(string + 1) == f_string_ascii_e_s.string[0]) { - flag |= F_print_format_flag_exponent_d; - ++string; - } - else if (*(string + 1) == f_string_ascii_E_s.string[0]) { - flag |= F_print_format_flag_exponent_d | F_print_format_flag_exponent_upper_d; - ++string; - } - else if (*(string + 1) == f_string_ascii_g_s.string[0]) { - flag |= F_print_format_flag_exponent_either_d; - ++string; - } - else if (*(string + 1) == f_string_ascii_G_s.string[0]) { - flag |= F_print_format_flag_exponent_either_d | F_print_format_flag_exponent_upper_d; - ++string; - } - } - } - else if (*string == f_string_ascii_i_s.string[0]) { - type = f_print_format_type_signed_32_e; - if (*(string + 1) == f_string_ascii_i_s.string[0]) { - if (*(string + 2) == f_string_ascii_i_s.string[0]) { - type = f_print_format_type_signed_8_e; - string += 2; + break; } - else { - type = f_print_format_type_signed_16_e; - ++string; - } - } - else if (*(string + 1) == f_string_ascii_l_s.string[0]) { - if (*(string + 2) == f_string_ascii_l_s.string[0]) { - type = f_print_format_type_signed_128_e; - string += 2; - } - else { - type = f_print_format_type_signed_64_e; - ++string; - } - } - else if (*(string + 1) == f_string_ascii_n_s.string[0]) { - type = f_print_format_type_signed_number_e; - ++string; - } - } - else if (*string == f_string_ascii_q_s.string[0]) { - const f_string_static_t value = va_arg(*ap, f_string_static_t); - - if (flag & F_print_format_flag_range_d) { - const f_string_range_t partial = va_arg(*ap, f_string_range_t); - - if (flag & F_print_format_flag_ignore_index_d) { - const f_array_lengths_t except_at = va_arg(*ap, f_array_lengths_t); - f_string_ranges_t except_in = f_string_ranges_t_initialize; - - if (flag & F_print_format_flag_ignore_range_d) { - except_in = va_arg(*ap, f_string_ranges_t); - } + else if (*string == f_string_ascii_S_s.string[0]) { + const f_string_t value = va_arg(apl, f_string_t); - if (partial.start > partial.stop) { - *status = F_data_not; + *status = f_print_safely_terminated(value, stream); - return string; - } - - f_array_length_t length = (partial.stop - partial.start) + 1; - - if (length + partial.start > value.used) { - length = value.used - partial.start; - } - - if (flag & F_print_format_flag_trim_d) { - *status = private_fl_print_trim_except_in(value.string, partial.start, length, except_at, except_in, stream); - } - else { - *status = f_print_except_in(value.string, partial.start, length, except_at, except_in, stream); - } + break; } - else if (flag & F_print_format_flag_ignore_range_d) { - const f_array_lengths_t except_at = f_array_lengths_t_initialize; - const f_string_ranges_t except_in = va_arg(*ap, f_string_ranges_t); + else if (*string == f_string_ascii_U_s.string[0]) { + type = f_print_format_type_unsigned_32_e; + flag |= F_print_format_flag_uppercase_d; - if (partial.start > partial.stop) { - *status = F_data_not; - - return string; + if (*(string + 1) == f_string_ascii_I_s.string[0]) { + if (*(string + 2) == f_string_ascii_I_s.string[0]) { + type = f_print_format_type_unsigned_8_e; + string += 2; + } + else { + type = f_print_format_type_unsigned_16_e; + ++string; + } } - - f_array_length_t length = (partial.stop - partial.start) + 1; - - if (length + partial.start > value.used) { - length = value.used - partial.start; + else if (*(string + 1) == f_string_ascii_L_s.string[0]) { + if (*(string + 2) == f_string_ascii_L_s.string[0]) { + type = f_print_format_type_unsigned_128_e; + string += 2; + } + else { + type = f_print_format_type_unsigned_64_e; + ++string; + } } - - if (flag & F_print_format_flag_trim_d) { - *status = private_fl_print_trim_except_in(value.string, partial.start, length, except_at, except_in, stream); - } - else { - *status = f_print_except_in(value.string, partial.start, length, except_at, except_in, stream); + else if (*(string + 1) == f_string_ascii_N_s.string[0]) { + type = f_print_format_type_unsigned_number_e; + ++string; } } else { - const f_array_lengths_t except_at = f_array_lengths_t_initialize; - const f_string_ranges_t except_in = va_arg(*ap, f_string_ranges_t); + *status = F_status_set_error(F_valid_not); - if (partial.start > partial.stop) { - *status = F_data_not; + break; + } + } + else if (*string < 0x60) { + if (*string == f_string_ascii_Z_s.string[0]) { + type = f_print_format_type_size_e; + flag |= F_print_format_flag_uppercase_d; + } + else if (*string == f_string_ascii_bracket_open_s.string[0]) { + const f_color_set_t value = va_arg(apl, f_color_set_t); - return string; + if (value.before) { + *status = f_print_dynamic_raw(*value.before, stream); } - f_array_length_t length = (partial.stop - partial.start) + 1; + break; + } + else if (*string == f_string_ascii_bracket_close_s.string[0]) { + const f_color_set_t value = va_arg(apl, f_color_set_t); - if (length + partial.start > value.used) { - length = value.used - partial.start; + if (value.after) { + *status = f_print_dynamic_raw(*value.after, stream); } - if (flag & F_print_format_flag_trim_d) { - *status = private_fl_print_trim(value.string + partial.start, length, stream); - } - else { - *status = f_print(value.string + partial.start, length, stream); - } + break; } - } - else if (flag & F_print_format_flag_ignore_index_d) { - const f_array_lengths_t except_at = va_arg(*ap, f_array_lengths_t); - f_string_ranges_t except_in = f_string_ranges_t_initialize; + else if (*string == f_string_ascii_caret_s.string[0]) { + base = 10; - if (flag & F_print_format_flag_ignore_range_d) { - except_in = va_arg(*ap, f_string_ranges_t); + continue; } + else if (*string == f_string_ascii_underscore_s.string[0]) { + base = 16; - if (flag & F_print_format_flag_trim_d) { - *status = private_fl_print_trim_except_in(value.string, 0, value.used, except_at, except_in, stream); + continue; } else { - *status = f_print_except_in_dynamic(value, except_at, except_in, stream); - } - } - else if (flag & F_print_format_flag_ignore_range_d) { - const f_array_lengths_t except_at = f_array_lengths_t_initialize; - const f_string_ranges_t except_in = va_arg(*ap, f_string_ranges_t); + *status = F_status_set_error(F_valid_not); - if (flag & F_print_format_flag_trim_d) { - *status = private_fl_print_trim_except_in(value.string, 0, value.used, except_at, except_in, stream); - } - else { - *status = f_print_except_in_dynamic(value, except_at, except_in, stream); - } - } - else { - if (flag & F_print_format_flag_trim_d) { - *status = private_fl_print_trim(value.string, value.used, stream); - } - else { - *status = f_print_dynamic(value, stream); + break; } } + else if (*string < 0x72) { + if (*string == f_string_ascii_c_s.string[0]) { + const char value = (char) va_arg(apl, uint32_t); - return string; - } - else { - *status = F_status_set_error(F_valid_not); - - return string; - } - } - else { - if (*string == f_string_ascii_r_s.string[0]) { - const f_string_static_t value = va_arg(*ap, f_string_static_t); - - if (flag & F_print_format_flag_range_d) { - const f_string_range_t partial = va_arg(*ap, f_string_range_t); - - if (flag & F_print_format_flag_ignore_index_d) { - const f_array_lengths_t except_at = va_arg(*ap, f_array_lengths_t); - f_string_ranges_t except_in = f_string_ranges_t_initialize; - - if (flag & F_print_format_flag_ignore_range_d) { - except_in = va_arg(*ap, f_string_ranges_t); + if (!fputc_unlocked(value, stream)) { + *status = F_status_set_error(F_output); } - if (partial.start > partial.stop) { - *status = F_data_not; - - return string; + break; + } + else if (*string == f_string_ascii_d_s.string[0]) { + type = f_print_format_type_double_32_e; + + if (*(string + 1)) { + if (*(string + 1) == f_string_ascii_L_s.string[0]) { + type = f_print_format_type_double_64_e; + + if (*(string + 2) == f_string_ascii_e_s.string[0]) { + flag |= F_print_format_flag_exponent_d; + string += 2; + } + else if (*(string + 2) == f_string_ascii_E_s.string[0]) { + flag |= F_print_format_flag_exponent_d | F_print_format_flag_exponent_upper_d; + string += 2; + } + else if (*(string + 2) == f_string_ascii_g_s.string[0]) { + flag |= F_print_format_flag_exponent_either_d; + string += 2; + } + else if (*(string + 2) == f_string_ascii_G_s.string[0]) { + flag |= F_print_format_flag_exponent_either_d | F_print_format_flag_exponent_upper_d; + string += 2; + } + else { + ++string; + } + } + else if (*(string + 1) == f_string_ascii_e_s.string[0]) { + flag |= F_print_format_flag_exponent_d; + ++string; + } + else if (*(string + 1) == f_string_ascii_E_s.string[0]) { + flag |= F_print_format_flag_exponent_d | F_print_format_flag_exponent_upper_d; + ++string; + } + else if (*(string + 1) == f_string_ascii_g_s.string[0]) { + flag |= F_print_format_flag_exponent_either_d; + ++string; + } + else if (*(string + 1) == f_string_ascii_G_s.string[0]) { + flag |= F_print_format_flag_exponent_either_d | F_print_format_flag_exponent_upper_d; + ++string; + } } - - f_array_length_t length = (partial.stop - partial.start) + 1; - - if (length + partial.start > value.used) { - length = value.used - partial.start; + } + else if (*string == f_string_ascii_i_s.string[0]) { + type = f_print_format_type_signed_32_e; + + if (*(string + 1) == f_string_ascii_i_s.string[0]) { + if (*(string + 2) == f_string_ascii_i_s.string[0]) { + type = f_print_format_type_signed_8_e; + string += 2; + } + else { + type = f_print_format_type_signed_16_e; + ++string; + } } - - if (flag & F_print_format_flag_trim_d) { - *status = private_fl_print_trim_except_in_raw(value.string, partial.start, length, except_at, except_in, stream); + else if (*(string + 1) == f_string_ascii_l_s.string[0]) { + if (*(string + 2) == f_string_ascii_l_s.string[0]) { + type = f_print_format_type_signed_128_e; + string += 2; + } + else { + type = f_print_format_type_signed_64_e; + ++string; + } } - else { - *status = f_print_except_in_raw(value.string, partial.start, length, except_at, except_in, stream); + else if (*(string + 1) == f_string_ascii_n_s.string[0]) { + type = f_print_format_type_signed_number_e; + ++string; } } - else if (flag & F_print_format_flag_ignore_range_d) { - const f_array_lengths_t except_at = f_array_lengths_t_initialize; - const f_string_ranges_t except_in = va_arg(*ap, f_string_ranges_t); - - if (partial.start > partial.stop) { - *status = F_data_not; - - return string; + else if (*string == f_string_ascii_q_s.string[0]) { + const f_string_static_t value = va_arg(apl, f_string_static_t); + + if (flag & F_print_format_flag_range_d) { + const f_string_range_t partial = va_arg(apl, f_string_range_t); + + if (flag & F_print_format_flag_ignore_index_d) { + const f_array_lengths_t except_at = va_arg(apl, f_array_lengths_t); + f_string_ranges_t except_in = f_string_ranges_t_initialize; + + if (flag & F_print_format_flag_ignore_range_d) { + except_in = va_arg(apl, f_string_ranges_t); + } + + if (partial.start > partial.stop) { + *status = F_data_not; + + break; + } + + f_array_length_t length = (partial.stop - partial.start) + 1; + + if (length + partial.start > value.used) { + length = value.used - partial.start; + } + + if (flag & F_print_format_flag_trim_d) { + *status = private_fl_print_trim_except_in(value.string, partial.start, length, except_at, except_in, stream); + } + else { + *status = f_print_except_in(value.string, partial.start, length, except_at, except_in, stream); + } + } + else if (flag & F_print_format_flag_ignore_range_d) { + const f_array_lengths_t except_at = f_array_lengths_t_initialize; + const f_string_ranges_t except_in = va_arg(apl, f_string_ranges_t); + + if (partial.start > partial.stop) { + *status = F_data_not; + + break; + } + + f_array_length_t length = (partial.stop - partial.start) + 1; + + if (length + partial.start > value.used) { + length = value.used - partial.start; + } + + if (flag & F_print_format_flag_trim_d) { + *status = private_fl_print_trim_except_in(value.string, partial.start, length, except_at, except_in, stream); + } + else { + *status = f_print_except_in(value.string, partial.start, length, except_at, except_in, stream); + } + } + else { + const f_array_lengths_t except_at = f_array_lengths_t_initialize; + const f_string_ranges_t except_in = va_arg(apl, f_string_ranges_t); + + if (partial.start > partial.stop) { + *status = F_data_not; + + break; + } + + f_array_length_t length = (partial.stop - partial.start) + 1; + + if (length + partial.start > value.used) { + length = value.used - partial.start; + } + + if (flag & F_print_format_flag_trim_d) { + *status = private_fl_print_trim(value.string + partial.start, length, stream); + } + else { + *status = f_print(value.string + partial.start, length, stream); + } + } } - - f_array_length_t length = (partial.stop - partial.start) + 1; - - if (length + partial.start > value.used) { - length = value.used - partial.start; + else if (flag & F_print_format_flag_ignore_index_d) { + const f_array_lengths_t except_at = va_arg(apl, f_array_lengths_t); + f_string_ranges_t except_in = f_string_ranges_t_initialize; + + if (flag & F_print_format_flag_ignore_range_d) { + except_in = va_arg(apl, f_string_ranges_t); + } + + if (flag & F_print_format_flag_trim_d) { + *status = private_fl_print_trim_except_in(value.string, 0, value.used, except_at, except_in, stream); + } + else { + *status = f_print_except_in_dynamic(value, except_at, except_in, stream); + } } - - if (flag & F_print_format_flag_trim_d) { - *status = private_fl_print_trim_except_in_raw(value.string, partial.start, length, except_at, except_in, stream); + else if (flag & F_print_format_flag_ignore_range_d) { + const f_array_lengths_t except_at = f_array_lengths_t_initialize; + const f_string_ranges_t except_in = va_arg(apl, f_string_ranges_t); + + if (flag & F_print_format_flag_trim_d) { + *status = private_fl_print_trim_except_in(value.string, 0, value.used, except_at, except_in, stream); + } + else { + *status = f_print_except_in_dynamic(value, except_at, except_in, stream); + } } else { - *status = f_print_except_in_raw(value.string, partial.start, length, except_at, except_in, stream); + if (flag & F_print_format_flag_trim_d) { + *status = private_fl_print_trim(value.string, value.used, stream); + } + else { + *status = f_print_dynamic(value, stream); + } } + + break; } else { - const f_array_lengths_t except_at = f_array_lengths_t_initialize; - const f_string_ranges_t except_in = va_arg(*ap, f_string_ranges_t); - - if (partial.start > partial.stop) { - *status = F_data_not; + *status = F_status_set_error(F_valid_not); - return string; + break; + } + } + else { + if (*string == f_string_ascii_r_s.string[0]) { + const f_string_static_t value = va_arg(apl, f_string_static_t); + + if (flag & F_print_format_flag_range_d) { + const f_string_range_t partial = va_arg(apl, f_string_range_t); + + if (flag & F_print_format_flag_ignore_index_d) { + const f_array_lengths_t except_at = va_arg(apl, f_array_lengths_t); + f_string_ranges_t except_in = f_string_ranges_t_initialize; + + if (flag & F_print_format_flag_ignore_range_d) { + except_in = va_arg(apl, f_string_ranges_t); + } + + if (partial.start > partial.stop) { + *status = F_data_not; + + break; + } + + f_array_length_t length = (partial.stop - partial.start) + 1; + + if (length + partial.start > value.used) { + length = value.used - partial.start; + } + + if (flag & F_print_format_flag_trim_d) { + *status = private_fl_print_trim_except_in_raw(value.string, partial.start, length, except_at, except_in, stream); + } + else { + *status = f_print_except_in_raw(value.string, partial.start, length, except_at, except_in, stream); + } + } + else if (flag & F_print_format_flag_ignore_range_d) { + const f_array_lengths_t except_at = f_array_lengths_t_initialize; + const f_string_ranges_t except_in = va_arg(apl, f_string_ranges_t); + + if (partial.start > partial.stop) { + *status = F_data_not; + + break; + } + + f_array_length_t length = (partial.stop - partial.start) + 1; + + if (length + partial.start > value.used) { + length = value.used - partial.start; + } + + if (flag & F_print_format_flag_trim_d) { + *status = private_fl_print_trim_except_in_raw(value.string, partial.start, length, except_at, except_in, stream); + } + else { + *status = f_print_except_in_raw(value.string, partial.start, length, except_at, except_in, stream); + } + } + else { + const f_array_lengths_t except_at = f_array_lengths_t_initialize; + const f_string_ranges_t except_in = va_arg(apl, f_string_ranges_t); + + if (partial.start > partial.stop) { + *status = F_data_not; + + break; + } + + f_array_length_t length = (partial.stop - partial.start) + 1; + + if (length + partial.start > value.used) { + length = value.used - partial.start; + } + + if (flag & F_print_format_flag_trim_d) { + *status = private_fl_print_trim_raw(value.string + partial.start, length, stream); + } + else { + *status = f_print_raw(value.string + partial.start, length, stream); + } + } } - - f_array_length_t length = (partial.stop - partial.start) + 1; - - if (length + partial.start > value.used) { - length = value.used - partial.start; + else if (flag & F_print_format_flag_ignore_index_d) { + const f_array_lengths_t except_at = va_arg(apl, f_array_lengths_t); + f_string_ranges_t except_in = f_string_ranges_t_initialize; + + if (flag & F_print_format_flag_ignore_range_d) { + except_in = va_arg(apl, f_string_ranges_t); + } + + if (flag & F_print_format_flag_trim_d) { + *status = private_fl_print_trim_except_in_raw(value.string, 0, value.used, except_at, except_in, stream); + } + else { + *status = f_print_except_in_dynamic_raw(value, except_at, except_in, stream); + } } - - if (flag & F_print_format_flag_trim_d) { - *status = private_fl_print_trim_raw(value.string + partial.start, length, stream); + else if (flag & F_print_format_flag_ignore_range_d) { + const f_array_lengths_t except_at = f_array_lengths_t_initialize; + const f_string_ranges_t except_in = va_arg(apl, f_string_ranges_t); + + if (flag & F_print_format_flag_trim_d) { + *status = private_fl_print_trim_except_in_raw(value.string, 0, value.used, except_at, except_in, stream); + } + else { + *status = f_print_except_in_dynamic_raw(value, except_at, except_in, stream); + } } else { - *status = f_print_raw(value.string + partial.start, length, stream); + if (flag & F_print_format_flag_trim_d) { + *status = private_fl_print_trim_raw(value.string, value.used, stream); + } + else { + *status = f_print_dynamic_raw(value, stream); + } } - } - } - else if (flag & F_print_format_flag_ignore_index_d) { - const f_array_lengths_t except_at = va_arg(*ap, f_array_lengths_t); - f_string_ranges_t except_in = f_string_ranges_t_initialize; - if (flag & F_print_format_flag_ignore_range_d) { - except_in = va_arg(*ap, f_string_ranges_t); + break; } + else if (*string == f_string_ascii_s_s.string[0]) { + const f_string_t value = va_arg(apl, f_string_t); - if (flag & F_print_format_flag_trim_d) { - *status = private_fl_print_trim_except_in_raw(value.string, 0, value.used, except_at, except_in, stream); - } - else { - *status = f_print_except_in_dynamic_raw(value, except_at, except_in, stream); - } - } - else if (flag & F_print_format_flag_ignore_range_d) { - const f_array_lengths_t except_at = f_array_lengths_t_initialize; - const f_string_ranges_t except_in = va_arg(*ap, f_string_ranges_t); + *status = f_print_terminated(value, stream); - if (flag & F_print_format_flag_trim_d) { - *status = private_fl_print_trim_except_in_raw(value.string, 0, value.used, except_at, except_in, stream); - } - else { - *status = f_print_except_in_dynamic_raw(value, except_at, except_in, stream); - } - } - else { - if (flag & F_print_format_flag_trim_d) { - *status = private_fl_print_trim_raw(value.string, value.used, stream); - } - else { - *status = f_print_dynamic_raw(value, stream); + break; } - } - - return string; - } - else if (*string == f_string_ascii_s_s.string[0]) { - const f_string_t value = va_arg(*ap, f_string_t); + else if (*string == f_string_ascii_u_s.string[0]) { + type = f_print_format_type_unsigned_32_e; - *status = f_print_terminated(value, stream); - - return string; - } - else if (*string == f_string_ascii_u_s.string[0]) { - type = f_print_format_type_unsigned_32_e; - - if (*(string + 1) == f_string_ascii_i_s.string[0]) { - if (*(string + 2) == f_string_ascii_i_s.string[0]) { - type = f_print_format_type_unsigned_8_e; - string += 2; - } - else { - type = f_print_format_type_unsigned_16_e; - ++string; + if (*(string + 1) == f_string_ascii_i_s.string[0]) { + if (*(string + 2) == f_string_ascii_i_s.string[0]) { + type = f_print_format_type_unsigned_8_e; + string += 2; + } + else { + type = f_print_format_type_unsigned_16_e; + ++string; + } + } + else if (*(string + 1) == f_string_ascii_l_s.string[0]) { + if (*(string + 2) == f_string_ascii_l_s.string[0]) { + type = f_print_format_type_unsigned_128_e; + string += 2; + } + else { + type = f_print_format_type_unsigned_64_e; + ++string; + } + } + else if (*(string + 1) == f_string_ascii_n_s.string[0]) { + type = f_print_format_type_unsigned_number_e; + ++string; + } } - } - else if (*(string + 1) == f_string_ascii_l_s.string[0]) { - if (*(string + 2) == f_string_ascii_l_s.string[0]) { - type = f_print_format_type_unsigned_128_e; - string += 2; + else if (*string == f_string_ascii_z_s.string[0]) { + type = f_print_format_type_size_e; } else { - type = f_print_format_type_unsigned_64_e; - ++string; + *status = F_status_set_error(F_valid_not); + + break; } } - else if (*(string + 1) == f_string_ascii_n_s.string[0]) { - type = f_print_format_type_unsigned_number_e; - ++string; - } - } - else if (*string == f_string_ascii_z_s.string[0]) { - type = f_print_format_type_size_e; - } - else { - *status = F_status_set_error(F_valid_not); - - return string; - } - } - - f_conversion_data_t conversion_data = macro_f_conversion_data_t_initialize(base, 0, 1); - - if (flag & F_print_format_flag_align_left_d) { - conversion_data.flag |= F_conversion_data_flag_align_left_d; - } - - if (flag & F_print_format_flag_convert_d) { - conversion_data.flag |= F_conversion_data_flag_base_prepend_d; - } - - if (flag & F_print_format_flag_sign_always_d) { - conversion_data.flag |= F_conversion_data_flag_sign_always_d; - } - - if (flag & F_print_format_flag_sign_pad_d) { - conversion_data.flag |= F_conversion_data_flag_sign_pad_d; - } - - if (flag & F_print_format_flag_uppercase_d) { - conversion_data.flag |= F_conversion_data_flag_base_upper_d; - } - - if (flag & F_print_format_flag_zeros_leading_d) { - conversion_data.flag |= F_conversion_data_flag_zeros_leading_d; - } - - if (flag & F_print_format_flag_width_value_d) { - width = va_arg(*ap, int); - } - if (flag & F_print_format_flag_precision_value_d) { - precision = va_arg(*ap, int); - } + f_conversion_data_t conversion_data = macro_f_conversion_data_t_initialize(base, 0, 1); - // @fixme precision and width can be used together, see: "'%10.2f'". - if (flag & F_print_format_flag_width_d) { - conversion_data.width = width; - } - else if (flag & F_print_format_flag_precision_d) { - conversion_data.width = precision; - } + if (flag & F_print_format_flag_align_left_d) { + conversion_data.flag |= F_conversion_data_flag_align_left_d; + } - if (type == f_print_format_type_signed_8_e) { - const int8_t value = (int8_t) va_arg(*ap, int); + if (flag & F_print_format_flag_convert_d) { + conversion_data.flag |= F_conversion_data_flag_base_prepend_d; + } - *status = f_conversion_number_signed_print((f_number_signed_t) value, conversion_data, stream); - } - else if (type == f_print_format_type_signed_16_e) { - const int16_t value = (int16_t) va_arg(*ap, int); + if (flag & F_print_format_flag_sign_always_d) { + conversion_data.flag |= F_conversion_data_flag_sign_always_d; + } - *status = f_conversion_number_signed_print((f_number_signed_t) value, conversion_data, stream); - } - else if (type == f_print_format_type_signed_32_e) { - *status = f_conversion_number_signed_print((f_number_signed_t) va_arg(*ap, int32_t), conversion_data, stream); - } - else if (type == f_print_format_type_signed_64_e) { - *status = f_conversion_number_signed_print((f_number_signed_t) va_arg(*ap, int64_t), conversion_data, stream); - } - else if (type == f_print_format_type_signed_128_e) { - *status = f_conversion_number_signed_print((f_number_signed_t) va_arg(*ap, f_int_128_t), conversion_data, stream); - } - else if (type == f_print_format_type_signed_number_e) { - *status = f_conversion_number_signed_print(va_arg(*ap, f_number_signed_t), conversion_data, stream); - } - else if (type == f_print_format_type_size_e) { - *status = f_conversion_number_unsigned_print((f_number_unsigned_t) va_arg(*ap, size_t), conversion_data, stream); - } - else if (type == f_print_format_type_unsigned_8_e) { - const uint8_t value = (uint8_t) va_arg(*ap, unsigned); + if (flag & F_print_format_flag_sign_pad_d) { + conversion_data.flag |= F_conversion_data_flag_sign_pad_d; + } - *status = f_conversion_number_unsigned_print((f_number_unsigned_t) value, conversion_data, stream); - } - else if (type == f_print_format_type_unsigned_16_e) { - const uint16_t value = (uint16_t) va_arg(*ap, unsigned); + if (flag & F_print_format_flag_uppercase_d) { + conversion_data.flag |= F_conversion_data_flag_base_upper_d; + } - *status = f_conversion_number_unsigned_print((f_number_unsigned_t) value, conversion_data, stream); - } - else if (type == f_print_format_type_unsigned_32_e) { - *status = f_conversion_number_unsigned_print((f_number_unsigned_t) va_arg(*ap, uint32_t), conversion_data, stream); - } - else if (type == f_print_format_type_unsigned_64_e) { - *status = f_conversion_number_unsigned_print((f_number_unsigned_t) va_arg(*ap, uint64_t), conversion_data, stream); - } - else if (type == f_print_format_type_unsigned_128_e) { - *status = f_conversion_number_unsigned_print((f_number_unsigned_t) va_arg(*ap, f_uint_128_t), conversion_data, stream); - } - else if (type == f_print_format_type_unsigned_number_e) { - *status = f_conversion_number_unsigned_print(va_arg(*ap, f_number_unsigned_t), conversion_data, stream); - } - else if (type == f_print_format_type_double_32_e || type == f_print_format_type_double_64_e) { - int f = 0; - char format[33]; - char buffer[129]; + if (flag & F_print_format_flag_zeros_leading_d) { + conversion_data.flag |= F_conversion_data_flag_zeros_leading_d; + } - memset(format, 0, 33); - memset(buffer, 0, 129); + if (flag & F_print_format_flag_width_value_d) { + width = va_arg(apl, int); + } - format[f++] = f_string_ascii_percent_s.string[0]; + if (flag & F_print_format_flag_precision_value_d) { + precision = va_arg(apl, int); + } - if (flag & F_print_format_flag_sign_always_d) { - format[f++] = f_string_ascii_plus_s.string[0]; - } - else if (flag & F_print_format_flag_sign_pad_d) { - format[f++] = f_string_ascii_space_s.string[0]; - } + // @fixme precision and width can be used together, see: "'%10.2f'". + if (flag & F_print_format_flag_width_d) { + conversion_data.width = width; + } + else if (flag & F_print_format_flag_precision_d) { + conversion_data.width = precision; + } - if (flag & F_print_format_flag_align_left_d) { - format[f++] = f_string_ascii_minus_s.string[0]; - } + if (type == f_print_format_type_signed_8_e) { + const int8_t value = (int8_t) va_arg(apl, signed int); - if (flag & F_print_format_flag_zeros_leading_d) { - format[f++] = f_string_ascii_0_s.string[0]; - } + *status = f_conversion_number_signed_print((f_number_signed_t) value, conversion_data, stream); + } + else if (type == f_print_format_type_signed_16_e) { + const int16_t value = (int16_t) va_arg(apl, signed int); - if (flag & F_print_format_flag_width_d) { - format[f++] = f_string_ascii_asterisk_s.string[0]; - } + *status = f_conversion_number_signed_print((f_number_signed_t) value, conversion_data, stream); + } + else if (type == f_print_format_type_signed_32_e) { + *status = f_conversion_number_signed_print((f_number_signed_t) va_arg(apl, int32_t), conversion_data, stream); + } + else if (type == f_print_format_type_signed_64_e) { + *status = f_conversion_number_signed_print((f_number_signed_t) va_arg(apl, int64_t), conversion_data, stream); + } + else if (type == f_print_format_type_signed_128_e) { + *status = f_conversion_number_signed_print((f_number_signed_t) va_arg(apl, f_int_128_t), conversion_data, stream); + } + else if (type == f_print_format_type_signed_number_e) { + *status = f_conversion_number_signed_print(va_arg(apl, f_number_signed_t), conversion_data, stream); + } + else if (type == f_print_format_type_size_e) { + *status = f_conversion_number_unsigned_print((f_number_unsigned_t) va_arg(apl, size_t), conversion_data, stream); + } + else if (type == f_print_format_type_unsigned_8_e) { + const uint8_t value = (uint8_t) va_arg(apl, unsigned int); - if (flag & F_print_format_flag_precision_d) { - format[f++] = f_string_ascii_period_s.string[0]; - format[f++] = f_string_ascii_asterisk_s.string[0]; - } + *status = f_conversion_number_unsigned_print((f_number_unsigned_t) value, conversion_data, stream); + } + else if (type == f_print_format_type_unsigned_16_e) { + const uint16_t value = (uint16_t) va_arg(apl, unsigned int); - if (flag & F_print_format_flag_exponent_d) { - if (flag & F_print_format_flag_exponent_upper_d) { - format[f++] = f_string_ascii_E_s.string[0]; + *status = f_conversion_number_unsigned_print((f_number_unsigned_t) value, conversion_data, stream); } - else { - format[f++] = f_string_ascii_e_s.string[0]; + else if (type == f_print_format_type_unsigned_32_e) { + *status = f_conversion_number_unsigned_print((f_number_unsigned_t) va_arg(apl, uint32_t), conversion_data, stream); } - } - else if (flag & F_print_format_flag_exponent_either_d) { - if (flag & F_print_format_flag_exponent_upper_d) { - format[f++] = f_string_ascii_G_s.string[0]; + else if (type == f_print_format_type_unsigned_64_e) { + *status = f_conversion_number_unsigned_print((f_number_unsigned_t) va_arg(apl, uint64_t), conversion_data, stream); } - else { - format[f++] = f_string_ascii_g_s.string[0]; + else if (type == f_print_format_type_unsigned_128_e) { + *status = f_conversion_number_unsigned_print((f_number_unsigned_t) va_arg(apl, f_uint_128_t), conversion_data, stream); } - } - else { - format[f++] = f_string_ascii_f_s.string[0]; - } + else if (type == f_print_format_type_unsigned_number_e) { + *status = f_conversion_number_unsigned_print(va_arg(apl, f_number_unsigned_t), conversion_data, stream); + } + else if (type == f_print_format_type_double_32_e || type == f_print_format_type_double_64_e) { + unsigned int f = 0; + char format[33]; + char buffer[129]; - format[f] = 0; + memset(format, 0, 33); + memset(buffer, 0, 129); - if (type == f_print_format_type_double_32_e) { - const double value = va_arg(*ap, double); + format[f++] = f_string_ascii_percent_s.string[0]; - if (flag & F_print_format_flag_width_d) { - if (flag & F_print_format_flag_precision_d) { - snprintf(buffer, 128, format, width, precision, value); + if (flag & F_print_format_flag_sign_always_d) { + format[f++] = f_string_ascii_plus_s.string[0]; } - else { - snprintf(buffer, 128, format, width, value); + else if (flag & F_print_format_flag_sign_pad_d) { + format[f++] = f_string_ascii_space_s.string[0]; + } + + if (flag & F_print_format_flag_align_left_d) { + format[f++] = f_string_ascii_minus_s.string[0]; + } + + if (flag & F_print_format_flag_zeros_leading_d) { + format[f++] = f_string_ascii_0_s.string[0]; + } + + if (flag & F_print_format_flag_width_d) { + format[f++] = f_string_ascii_asterisk_s.string[0]; } - } - else if (flag & F_print_format_flag_precision_d) { - snprintf(buffer, 128, format, precision, value); - } - else { - snprintf(buffer, 128, format, value); - } - } - else { - const long double value = va_arg(*ap, long double); - if (flag & F_print_format_flag_width_d) { if (flag & F_print_format_flag_precision_d) { - snprintf(buffer, 128, format, width, precision, value); + format[f++] = f_string_ascii_period_s.string[0]; + format[f++] = f_string_ascii_asterisk_s.string[0]; + } + + if (flag & F_print_format_flag_exponent_d) { + if (flag & F_print_format_flag_exponent_upper_d) { + format[f++] = f_string_ascii_E_s.string[0]; + } + else { + format[f++] = f_string_ascii_e_s.string[0]; + } + } + else if (flag & F_print_format_flag_exponent_either_d) { + if (flag & F_print_format_flag_exponent_upper_d) { + format[f++] = f_string_ascii_G_s.string[0]; + } + else { + format[f++] = f_string_ascii_g_s.string[0]; + } } else { - snprintf(buffer, 128, format, width, value); + format[f++] = f_string_ascii_f_s.string[0]; } - } - else if (flag & F_print_format_flag_precision_d) { - snprintf(buffer, 128, format, precision, value); - } - else { - snprintf(buffer, 128, format, value); - } - } - *status = f_print_terminated(buffer, stream); - } + if (type == f_print_format_type_double_32_e) { + const double value = va_arg(apl, double); - return string; - } // for + if (flag & F_print_format_flag_width_d) { + if (flag & F_print_format_flag_precision_d) { + snprintf(buffer, 128, format, width, precision, value); + } + else { + snprintf(buffer, 128, format, width, value); + } + } + else if (flag & F_print_format_flag_precision_d) { + snprintf(buffer, 128, format, precision, value); + } + else { + snprintf(buffer, 128, format, value); + } + } + else { + const long double value = va_arg(apl, long double); + + if (flag & F_print_format_flag_width_d) { + if (flag & F_print_format_flag_precision_d) { + snprintf(buffer, 128, format, width, precision, value); + } + else { + snprintf(buffer, 128, format, width, value); + } + } + else if (flag & F_print_format_flag_precision_d) { + snprintf(buffer, 128, format, precision, value); + } + else { + snprintf(buffer, 128, format, value); + } + } - *status = F_status_set_error(F_valid_not); + *status = f_print_terminated(buffer, stream); + } - return string; - } -#endif // !defined(_di_fl_print_format_) || !defined(_di_fl_print_format_convert_) + va_end(apl); -#if !defined(_di_fl_print_format_) || !defined(_di_fl_print_format_convert_) - f_string_t private_fl_print_convert_number(f_string_t string, va_list *ap, unsigned int * const number, f_status_t * const status) { + break; + } // for - for (*number = 0; *string; ++string) { + if (F_status_is_error(*status)) break; - if (*string > 0x2f && *string < 0x3a) { - *number *= 10; - *number += 0xf & *string; - } - else if (*string == f_string_ascii_asterisk_s.string[0]) { - *number = va_arg(*ap, unsigned int); + if (!*string) { + *status = F_status_set_error(F_valid_not); - break; + break; + } } else { - - // Do not leave string on the non-digit and non-asterisk character. - --string; - - break; + if (!fputc_unlocked(*string, stream)) break; } } // for - // Do not leave string on the terminating NULL. - if (!string) { - --string; - } + va_end(apl); return string; } diff --git a/level_1/fl_print/c/private-print.h b/level_1/fl_print/c/private-print.h index 551b42e..272c3d2 100644 --- a/level_1/fl_print/c/private-print.h +++ b/level_1/fl_print/c/private-print.h @@ -72,31 +72,7 @@ extern "C" { * @see private_fl_print_convert_number() */ #if !defined(_di_fl_print_format_) || !defined(_di_fl_print_format_convert_) - extern f_string_t private_fl_print_format_convert(f_string_t string, FILE * const stream, va_list * const ap, f_status_t * const status) F_attribute_visibility_internal_d; -#endif // !defined(_di_fl_print_format_) || !defined(_di_fl_print_format_convert_) - -/** - * Helper function for processing the number in a convert string. - * - * This should be called to convert numbers after a '%', such as the field with or precision. - * - * On return the string will point to either the last consecutive character representing a number or the asterisk. - * - * @param string - * The current character position within the string. - * @param ap - * The variable arguments list. - * @param number - * The converted number. - * - * @return - * F_true on success and end of string (NULL) is found. - * F_false on success without reaching the end of string (NULL). - * - * @see va_arg() - */ -#if !defined(_di_fl_print_format_) || !defined(_di_fl_print_format_convert_) - extern f_string_t private_fl_print_convert_number(f_string_t string, va_list * const ap, unsigned int * const number, f_status_t * const status) F_attribute_visibility_internal_d; + extern f_string_t private_fl_print_format_convert(f_string_t string, FILE * const stream, va_list ap, f_status_t * const status) F_attribute_visibility_internal_d; #endif // !defined(_di_fl_print_format_) || !defined(_di_fl_print_format_convert_) /** diff --git a/level_2/fll_print/c/print.c b/level_2/fll_print/c/print.c index ac44e02..aba71c8 100644 --- a/level_2/fll_print/c/print.c +++ b/level_2/fll_print/c/print.c @@ -468,7 +468,7 @@ extern "C" { va_start(ap, output); - const f_status_t status = fl_print_string_va(string, output, &ap); + const f_status_t status = fl_print_string_va(string, output, ap); va_end(ap); @@ -479,7 +479,7 @@ extern "C" { #endif // _di_fll_print_format_ #ifndef _di_fll_print_format_convert_ - f_string_t fll_print_format_convert(const f_string_t string, FILE * const output, va_list * const ap, f_status_t * const status) { + f_string_t fll_print_format_convert(const f_string_t string, FILE * const output, va_list ap, f_status_t * const status) { flockfile(output); @@ -557,7 +557,7 @@ extern "C" { #endif // _di_fll_print_safely_terminated_ #ifndef _di_fll_print_string_va_ - f_status_t fll_print_string_va(const f_string_t string, FILE * const output, va_list * const ap) { + f_status_t fll_print_string_va(const f_string_t string, FILE * const output, va_list ap) { flockfile(output); diff --git a/level_2/fll_print/c/print.h b/level_2/fll_print/c/print.h index 45c662a..c8b598d 100644 --- a/level_2/fll_print/c/print.h +++ b/level_2/fll_print/c/print.h @@ -1013,7 +1013,7 @@ extern "C" { * @see fl_print_format_convert() */ #ifndef _di_fll_print_format_convert_ - extern f_string_t fll_print_format_convert(const f_string_t current, FILE * const output, va_list *ap, f_status_t *status); + extern f_string_t fll_print_format_convert(const f_string_t current, FILE * const output, va_list ap, f_status_t *status); #endif // _di_fll_print_format_convert_ /** @@ -1156,7 +1156,7 @@ extern "C" { * @see fl_print_string_va() */ #ifndef _di_fll_print_string_va_ - extern f_status_t fll_print_string_va(const f_string_t string, FILE * const output, va_list *ap); + extern f_status_t fll_print_string_va(const f_string_t string, FILE * const output, va_list ap); #endif // _di_fll_print_string_va_ /** -- 1.8.3.1