MCPcopy Create free account
hub / github.com/c42f/tinyformat / streamStateFromFormat

Function streamStateFromFormat

tinyformat.h:655–859  ·  view source on GitHub ↗

Parse a format string and set the stream state accordingly. The format mini-language recognized here is meant to be the one from C99, with the form "%[flags][width][.precision][length]type" with POSIX positional arguments extension. POSIX positional arguments extension: Conversions can be applied to the nth argument after the format in the argument list, rather than to the next unused argument.

Source from the content-addressed store, hash-verified

653// necessary to pull out variable width and precision. The function returns a
654// pointer to the character after the end of the current format spec.
655inline const char* streamStateFromFormat(std::ostream& out, bool& positionalMode,
656 bool& spacePadPositive,
657 int& ntrunc, const char* fmtStart,
658 const detail::FormatArg* args,
659 int& argIndex, int numArgs)
660{
661 TINYFORMAT_ASSERT(*fmtStart == '%');
662 // Reset stream state to defaults.
663 out.width(0);
664 out.precision(6);
665 out.fill(' ');
666 // Reset most flags; ignore irrelevant unitbuf & skipws.
667 out.unsetf(std::ios::adjustfield | std::ios::basefield |
668 std::ios::floatfield | std::ios::showbase | std::ios::boolalpha |
669 std::ios::showpoint | std::ios::showpos | std::ios::uppercase);
670 bool precisionSet = false;
671 bool widthSet = false;
672 int widthExtra = 0;
673 const char* c = fmtStart + 1;
674
675 // 1) Parse an argument index (if followed by '$') or a width possibly
676 // preceded with '0' flag.
677 if (*c >= '0' && *c <= '9') {
678 const char tmpc = *c;
679 int value = parseIntAndAdvance(c);
680 if (*c == '$') {
681 // value is an argument index
682 if (value > 0 && value <= numArgs)
683 argIndex = value - 1;
684 else
685 TINYFORMAT_ERROR("tinyformat: Positional argument out of range");
686 ++c;
687 positionalMode = true;
688 }
689 else if (positionalMode) {
690 TINYFORMAT_ERROR("tinyformat: Non-positional argument used after a positional one");
691 }
692 else {
693 if (tmpc == '0') {
694 // Use internal padding so that numeric values are
695 // formatted correctly, eg -00010 rather than 000-10
696 out.fill('0');
697 out.setf(std::ios::internal, std::ios::adjustfield);
698 }
699 if (value != 0) {
700 // Nonzero value means that we parsed width.
701 widthSet = true;
702 out.width(value);
703 }
704 }
705 }
706 else if (positionalMode) {
707 TINYFORMAT_ERROR("tinyformat: Non-positional argument used after a positional one");
708 }
709 // 2) Parse flags and width if we did not do it in previous step.
710 if (!widthSet) {
711 // Parse flags
712 for (;; ++c) {

Callers 1

formatImplFunction · 0.85

Calls

no outgoing calls

Tested by

no test coverage detected