Parse a format specifier from the format string Returns the format spec and advances the pointer past the specifier Format: %[flags][width][.precision][length]type
| 107 | // Returns the format spec and advances the pointer past the specifier |
| 108 | // Format: %[flags][width][.precision][length]type |
| 109 | inline FormatSpec parse_format_spec(const char*& format) FL_NOEXCEPT { |
| 110 | FormatSpec spec; |
| 111 | |
| 112 | if (*format != '%') { |
| 113 | return spec; |
| 114 | } |
| 115 | |
| 116 | ++format; // Skip the '%' |
| 117 | |
| 118 | // Handle literal '%' |
| 119 | if (*format == '%') { |
| 120 | spec.type = '%'; |
| 121 | ++format; |
| 122 | return spec; |
| 123 | } |
| 124 | |
| 125 | // Parse flags: -, +, space, #, 0 (can be in any order) |
| 126 | bool parsing_flags = true; |
| 127 | while (parsing_flags) { |
| 128 | switch (*format) { |
| 129 | case '-': |
| 130 | spec.left_align = true; |
| 131 | ++format; |
| 132 | break; |
| 133 | case '+': |
| 134 | spec.show_sign = true; |
| 135 | ++format; |
| 136 | break; |
| 137 | case ' ': |
| 138 | spec.space_sign = true; |
| 139 | ++format; |
| 140 | break; |
| 141 | case '#': |
| 142 | spec.alt_form = true; |
| 143 | ++format; |
| 144 | break; |
| 145 | case '0': |
| 146 | spec.zero_pad = true; |
| 147 | ++format; |
| 148 | break; |
| 149 | default: |
| 150 | parsing_flags = false; |
| 151 | break; |
| 152 | } |
| 153 | } |
| 154 | |
| 155 | // Parse width (decimal number) |
| 156 | if (*format >= '0' && *format <= '9') { |
| 157 | spec.width = 0; |
| 158 | while (*format >= '0' && *format <= '9') { |
| 159 | spec.width = spec.width * 10 + (*format - '0'); |
| 160 | ++format; |
| 161 | } |
| 162 | } |
| 163 | |
| 164 | // Parse precision for floating point |
| 165 | if (*format == '.') { |
| 166 | ++format; // Skip the '.' |