ReactOS 0.4.16-dev-1133-g947c03e
__crt_stdio_input::format_string_parser< Character > Class Template Reference

#include <corecrt_internal_stdio_input.h>

Collaboration diagram for __crt_stdio_input::format_string_parser< Character >:

Public Types

using traits = __acrt_stdio_char_traits< Character >
 
using char_type = Character
 
using unsigned_char_type = typename traits::unsigned_char_type
 
using int_type = typename traits::int_type
 

Public Member Functions

 format_string_parser (_In_ uint64_t const options, _In_z_ unsigned_char_type const *const format_it) throw ()
 
bool validate () const throw ()
 
bool advance () throw ()
 
errno_t error_code () const throw ()
 
format_directive_kind kind () const throw ()
 
unsigned_char_type literal_character_lead () const throw ()
 
unsigned_char_type literal_character_trail () const throw ()
 
bool suppress_assignment () const throw ()
 
uint64_t width () const throw ()
 
size_t length () const throw ()
 
conversion_mode mode () const throw ()
 
scanset_buffer< unsigned_char_type > constscanset () const throw ()
 

Private Member Functions

bool scan_optional_literal_character_trail_bytes_tchar (char) throw ()
 
bool scan_optional_literal_character_trail_bytes_tchar (wchar_t) throw ()
 
void scan_optional_assignment_suppressor () throw ()
 
bool scan_optional_field_width () throw ()
 
void scan_optional_length_modifier () throw ()
 
void scan_optional_wide_modifier () throw ()
 
bool should_default_to_wide (unsigned char const c) throw ()
 
bool should_default_to_wide (wchar_t const c) throw ()
 
void set_wide_for_c_s_or_scanset () throw ()
 
bool scan_conversion_specifier () throw ()
 
bool scan_scanset_range () throw ()
 
void reset_token_state () throw ()
 
void reset_token_state_for_error (errno_t const error_code) throw ()
 

Private Attributes

uint64_t _options
 
unsigned_char_type const_format_it
 
errno_t _error_code
 
format_directive_kind _kind
 
unsigned_char_type _literal_character_lead
 
unsigned_char_type _literal_character_trail
 
bool _suppress_assignment
 
uint64_t _width
 
length_modifier _length
 
bool _is_wide
 
conversion_mode _mode
 
scanset_buffer< unsigned_char_type_scanset
 

Detailed Description

template<typename Character>
class __crt_stdio_input::format_string_parser< Character >

Definition at line 451 of file corecrt_internal_stdio_input.h.

Member Typedef Documentation

◆ char_type

template<typename Character >
using __crt_stdio_input::format_string_parser< Character >::char_type = Character

Definition at line 456 of file corecrt_internal_stdio_input.h.

◆ int_type

template<typename Character >
using __crt_stdio_input::format_string_parser< Character >::int_type = typename traits::int_type

Definition at line 458 of file corecrt_internal_stdio_input.h.

◆ traits

template<typename Character >
using __crt_stdio_input::format_string_parser< Character >::traits = __acrt_stdio_char_traits<Character>

Definition at line 455 of file corecrt_internal_stdio_input.h.

◆ unsigned_char_type

template<typename Character >
using __crt_stdio_input::format_string_parser< Character >::unsigned_char_type = typename traits::unsigned_char_type

Definition at line 457 of file corecrt_internal_stdio_input.h.

Constructor & Destructor Documentation

◆ format_string_parser()

Member Function Documentation

◆ advance()

template<typename Character >
bool __crt_stdio_input::format_string_parser< Character >::advance ( )
throw (
)
inline

Definition at line 477 of file corecrt_internal_stdio_input.h.

478 {
479 if (_error_code != 0)
480 {
481 return false;
482 }
483
485
486 if (*_format_it == '\0')
487 {
489 return false;
490 }
491
492 if (traits::istspace(*_format_it))
493 {
495
496 while (traits::istspace(*_format_it))
497 ++_format_it;
498
499 return true;
500 }
501
502 if (_format_it[0] != '%' || _format_it[1] == '%')
503 {
506 _format_it += _format_it[0] != '%' ? 1 : 2;
507
509 }
510
512 ++_format_it; // Advance past the %
513
515
517 {
518 return false;
519 }
520
523
525 {
526 return false;
527 }
528
530 {
532 return false;
533 }
534
535 return true;
536 }
#define EINVAL
Definition: acclib.h:90
void reset_token_state_for_error(errno_t const error_code)
bool __cdecl is_length_valid(conversion_mode const mode, length_modifier const length)

Referenced by __crt_stdio_input::input_processor< Character, InputAdapter >::process().

◆ error_code()

◆ kind()

◆ length()

template<typename Character >
size_t __crt_stdio_input::format_string_parser< Character >::length ( ) const
throw (
)
inline

Definition at line 572 of file corecrt_internal_stdio_input.h.

573 {
575 switch (_mode)
576 {
580 return _is_wide ? sizeof(wchar_t) : sizeof(char);
581
589
592 }
593
594 return 0; // Unreachable
595 }
#define _ASSERTE(expr)
Definition: crtdbg.h:114
size_t __cdecl to_floating_point_length(length_modifier const length)
size_t __cdecl to_integer_length(length_modifier const length)
#define wchar_t
Definition: wchar.h:102

Referenced by __crt_stdio_input::input_processor< Character, InputAdapter >::process_floating_point_specifier(), __crt_stdio_input::input_processor< Character, InputAdapter >::process_string_specifier(), __crt_stdio_input::input_processor< Character, InputAdapter >::write_floating_point(), and __crt_stdio_input::input_processor< Character, InputAdapter >::write_integer().

◆ literal_character_lead()

◆ literal_character_trail()

◆ mode()

◆ reset_token_state()

template<typename Character >
void __crt_stdio_input::format_string_parser< Character >::reset_token_state ( )
throw (
)
inlineprivate

◆ reset_token_state_for_error()

◆ scan_conversion_specifier()

template<typename Character >
bool __crt_stdio_input::format_string_parser< Character >::scan_conversion_specifier ( )
throw (
)
inlineprivate

Definition at line 825 of file corecrt_internal_stdio_input.h.

826 {
827 switch (*_format_it)
828 {
829 case 'C':
830 case 'c':
831 {
832 // If no width was specified, use a default width of one character:
833 if (_width == 0)
834 _width = 1;
835
837
839 ++_format_it;
840 return true;
841 }
842
843 case 'S':
844 case 's':
845 {
847
849 ++_format_it;
850 return true;
851 }
852
853 case 'i':
854 case 'I':
855 {
857 ++_format_it;
858 return true;
859 }
860
861 case 'd':
862 {
864 ++_format_it;
865 return true;
866 }
867
868 case 'u':
869 {
871 ++_format_it;
872 return true;
873 }
874
875 case 'X':
876 case 'x':
877 {
879 ++_format_it;
880 return true;
881 }
882
883 case 'p':
884 {
885 _length = sizeof(void*) == 4
889 ++_format_it;
890 return true;
891 }
892
893 case 'o':
894 {
896 ++_format_it;
897 return true;
898 }
899
900 case 'A':
901 case 'a':
902 case 'E':
903 case 'e':
904 case 'F':
905 case 'f':
906 case 'G':
907 case 'g':
908 {
910 ++_format_it;
911 return true;
912 }
913
914 case '[':
915 {
917
919 ++_format_it;
920 return scan_scanset_range();
921 }
922
923 case 'n':
924 {
926 ++_format_it;
927 return true;
928 }
929
930 default:
931 {
933 return false;
934 }
935 }
936 }

Referenced by __crt_stdio_input::format_string_parser< Character >::advance().

◆ scan_optional_assignment_suppressor()

template<typename Character >
void __crt_stdio_input::format_string_parser< Character >::scan_optional_assignment_suppressor ( )
throw (
)
inlineprivate

Definition at line 636 of file corecrt_internal_stdio_input.h.

637 {
638 if (*_format_it != '*')
639 return;
640
642 ++_format_it;
643 return;
644 }

Referenced by __crt_stdio_input::format_string_parser< Character >::advance().

◆ scan_optional_field_width()

template<typename Character >
bool __crt_stdio_input::format_string_parser< Character >::scan_optional_field_width ( )
throw (
)
inlineprivate

Definition at line 646 of file corecrt_internal_stdio_input.h.

647 {
648 if (__crt_strtox::parse_digit(static_cast<char_type>(*_format_it)) > 9)
649 return true;
650
651 unsigned_char_type* width_end{};
652 uint64_t const width{traits::tcstoull(
653 reinterpret_cast<char_type const*>(_format_it),
654 reinterpret_cast<char_type**>(&width_end),
655 10)};
656
657 if (width == 0 || width_end == _format_it)
658 {
660 return false;
661 }
662
663 _width = width;
664 _format_it = width_end;
665 return true;
666 }
typename traits::unsigned_char_type unsigned_char_type
UINT64 uint64_t
Definition: types.h:77
GLint GLint GLsizei width
Definition: gl.h:1546
__forceinline unsigned __cdecl parse_digit(char const c)
#define const
Definition: zconf.h:233

Referenced by __crt_stdio_input::format_string_parser< Character >::advance().

◆ scan_optional_length_modifier()

template<typename Character >
void __crt_stdio_input::format_string_parser< Character >::scan_optional_length_modifier ( )
throw (
)
inlineprivate

Definition at line 668 of file corecrt_internal_stdio_input.h.

669 {
670 switch (*_format_it)
671 {
672 case 'h':
673 {
674 if (_format_it[1] == 'h')
675 {
676 _format_it += 2; // Advance past "hh"
678 }
679 else
680 {
681 _format_it += 1; // Advance past "h"
683 }
684
685 return;
686 }
687
688 case 'I':
689 {
690 // The I32, I64, and I length modifiers are Microsoft extensions.
691
692 if (_format_it[1] == '3' && _format_it[2] == '2')
693 {
694 _format_it += 3; // Advance past "I32"
696 return;
697 }
698
699 if (_format_it[1] == '6' && _format_it[2] == '4')
700 {
701 _format_it += 3; // Advance past "I64"
703 return;
704 }
705
706 // Some disambiguation is required for the standalone I length
707 // modifier. If the I is followed by a d, i, o, x, or X character,
708 // then we treat it as I32 on 32-bit platforms and I64 on 64-bit
709 // platforms. Otherwise, we do not treat it as a length modifier
710 // and instead treat it as a conversion specifier (equivalent to the
711 // lowercase i).
712 if (_format_it[1] == 'd' ||
713 _format_it[1] == 'i' ||
714 _format_it[1] == 'o' ||
715 _format_it[1] == 'u' ||
716 _format_it[1] == 'x' ||
717 _format_it[1] == 'X')
718 {
719 ++_format_it; // Advance past "I"
720 _length = sizeof(void*) == 4
723 return;
724 }
725
726 return;
727 }
728
729 case 'l':
730 {
731 if (_format_it[1] == 'l')
732 {
733 _format_it += 2; // Advance past "ll"
735 }
736 else
737 {
738 _format_it += 1; // Advance past "l"
740 }
741
742 return;
743 }
744
745 case 'L':
746 {
747 ++_format_it; // Advance past "L"
749 return;
750 }
751
752 case 'j':
753 {
754 ++_format_it; // Advance past "j"
756 return;
757 }
758
759 case 't':
760 {
761 ++_format_it; // Advance past "t"
763 return;
764 }
765
766 case 'z':
767 {
768 ++_format_it; // Advance past "z"
770 return;
771 }
772
773 case 'T':
774 {
775 ++_format_it; // Advance past "T"
777 return;
778 }
779 }
780 }

Referenced by __crt_stdio_input::format_string_parser< Character >::advance().

◆ scan_optional_literal_character_trail_bytes_tchar() [1/2]

template<typename Character >
bool __crt_stdio_input::format_string_parser< Character >::scan_optional_literal_character_trail_bytes_tchar ( char  )
throw (
)
inlineprivate

Definition at line 611 of file corecrt_internal_stdio_input.h.

612 {
614 {
615 return true;
616 }
617
618 // If we need a trail byte and we're at the end of the format string,
619 // the format string is malformed:
620 if (*_format_it == '\0')
621 {
623 return false;
624 }
625
627 ++_format_it;
628 return true;
629 }
#define isleadbyte(_c)
Definition: wchar.h:598
#define EILSEQ
Definition: errno.h:109

Referenced by __crt_stdio_input::format_string_parser< Character >::advance().

◆ scan_optional_literal_character_trail_bytes_tchar() [2/2]

template<typename Character >
bool __crt_stdio_input::format_string_parser< Character >::scan_optional_literal_character_trail_bytes_tchar ( wchar_t  )
throw (
)
inlineprivate

Definition at line 631 of file corecrt_internal_stdio_input.h.

632 {
633 return true; // There are no trail bytes for wide character strings
634 }

◆ scan_optional_wide_modifier()

template<typename Character >
void __crt_stdio_input::format_string_parser< Character >::scan_optional_wide_modifier ( )
throw (
)
inlineprivate

Definition at line 782 of file corecrt_internal_stdio_input.h.

783 {
784 if (*_format_it == 'w')
785 {
786 ++_format_it; // Advance past "w"
787 _is_wide = true;
788 return;
789 }
790
792 {
793 _is_wide = true;
794 return;
795 }
796 }

Referenced by __crt_stdio_input::format_string_parser< Character >::advance().

◆ scan_scanset_range()

template<typename Character >
bool __crt_stdio_input::format_string_parser< Character >::scan_scanset_range ( )
throw (
)
inlineprivate

Definition at line 938 of file corecrt_internal_stdio_input.h.

939 {
940 if (!_scanset.is_usable())
941 {
943 return false;
944 }
945
946 _scanset.reset();
947
948 bool const is_reject_set{*_format_it == '^'};
949 if (is_reject_set)
950 {
951 ++_format_it;
952 }
953
954 if (*_format_it == ']')
955 {
956 ++_format_it;
957 _scanset.set(static_cast<unsigned_char_type>(']'));
958 }
959
960 unsigned_char_type const* const first{_format_it};
961 unsigned_char_type const* last_range_end = nullptr;
962 for (; *_format_it != ']' && *_format_it != '\0'; ++_format_it)
963 {
964 // If the current character is not a hyphen, if its the end of a range,
965 // or if it's the first or last character in the scanset, treat it as a
966 // literal character and just add it to the table:
967 if (*_format_it != '-' || _format_it - 1 == last_range_end || _format_it == first || _format_it[1] == ']')
968 {
970 }
971 // Otherwise, we're pointing to a hyphen that falls between two other
972 // characters, so this is a range to be matched (e.g. [a-z]). Toggle
973 // the bits for each character in the range:
974 else
975 {
978 last_range_end = _format_it + 1;
979
980 // We support ranges in both directions ([a-z] and [z-a]). We
981 // can handle both simultaneously by transforming [z-a] into [a-z]:
983 {
986 upper_bound = c;
987 }
988
989 // Convert [lower_bound, upper_bound] into [lower_bound, upper_bound):
990 ++upper_bound;
991
993 {
994 _scanset.set(c);
995 }
996 }
997 }
998
999 if (*_format_it == '\0')
1000 {
1002 return false;
1003 }
1004
1005 if (is_reject_set)
1006 {
1007 _scanset.invert();
1008 }
1009
1010 ++_format_it; // Advance past ']'
1011 return true;
1012 }
_STLP_MOVE_TO_STD_NAMESPACE _ForwardIter upper_bound(_ForwardIter __first, _ForwardIter __last, const _Tp &__val)
Definition: _algo.h:507
_STLP_MOVE_TO_STD_NAMESPACE _ForwardIter lower_bound(_ForwardIter __first, _ForwardIter __last, const _Tp &__val)
Definition: _algo.h:481
#define ENOMEM
Definition: acclib.h:84
scanset_buffer< unsigned_char_type > _scanset
const GLubyte * c
Definition: glext.h:8905
const GLint * first
Definition: glext.h:5794
#define c
Definition: ke_i.h:80

Referenced by __crt_stdio_input::format_string_parser< Character >::scan_conversion_specifier().

◆ scanset()

◆ set_wide_for_c_s_or_scanset()

template<typename Character >
void __crt_stdio_input::format_string_parser< Character >::set_wide_for_c_s_or_scanset ( )
throw (
)
inlineprivate

◆ should_default_to_wide() [1/2]

template<typename Character >
bool __crt_stdio_input::format_string_parser< Character >::should_default_to_wide ( unsigned char const  c)
throw (
)
inlineprivate

Definition at line 798 of file corecrt_internal_stdio_input.h.

799 {
800 return c == 'C' || c == 'S';
801 }

Referenced by __crt_stdio_input::format_string_parser< Character >::scan_optional_wide_modifier().

◆ should_default_to_wide() [2/2]

template<typename Character >
bool __crt_stdio_input::format_string_parser< Character >::should_default_to_wide ( wchar_t const  c)
throw (
)
inlineprivate

Definition at line 803 of file corecrt_internal_stdio_input.h.

804 {
805 if (c == 'C' || c == 'S')
806 return false;
807
809 return true;
810
812 }
#define _CRT_INTERNAL_SCANF_LEGACY_WIDE_SPECIFIERS

◆ suppress_assignment()

◆ validate()

template<typename Character >
bool __crt_stdio_input::format_string_parser< Character >::validate ( ) const
throw (
)
inline

Definition at line 471 of file corecrt_internal_stdio_input.h.

472 {
473 _VALIDATE_RETURN(_format_it != nullptr, EINVAL, false);
474 return true;
475 }
#define _VALIDATE_RETURN(expr, errorcode, retexpr)

Referenced by __crt_stdio_input::input_processor< Character, InputAdapter >::process().

◆ width()

Member Data Documentation

◆ _error_code

◆ _format_it

◆ _is_wide

◆ _kind

◆ _length

◆ _literal_character_lead

◆ _literal_character_trail

◆ _mode

◆ _options

◆ _scanset

◆ _suppress_assignment

◆ _width


The documentation for this class was generated from the following file: