99 using ll_t =
long long;
101 uint32_t adjust_left : 1 = 0, add_sign : 1 = 0, use_width : 1 = 0, use_precision : 1 = 0;
102 uint32_t alternate_form : 1 = 0, zero_padding : 1 = 0, add_space : 1 = 0, locale_grouping : 1 = 0;
103 uint32_t field_width = 0, precision = 0, start = 0, end = 0, value_index = 0, width_index = 0, precision_index = 0;
105 parse_positional (
const char **stringp,
uint64_t *ap)
107 const char *p = *stringp;
109 if (parse_unsigned_integer (&p, &ui64) && *p ==
'$')
119 parse_directive (
const char **stringp,
size_t *indexp)
121 const char *p = *stringp;
122 size_t index = *indexp;
125 return "missing '%' at start";
129 if (parse_positional (&p, &ui64))
131 if (ui64 > 0 && ui64 <= 2147483647)
134 return "invalid positional specification";
137 const char *flags =
"-+#0 '";
138 while (
strchr (flags, *p))
141 case '-': adjust_left =
true;
goto default_case;
142 case '+': add_sign =
true;
goto default_case;
143 case '#': alternate_form =
true;
goto default_case;
144 case '0': zero_padding =
true;
goto default_case;
145 case ' ': add_space =
true;
goto default_case;
146 case '\'': locale_grouping =
true;
goto default_case;
147 default: default_case:
156 if (parse_positional (&p, &ui64))
158 if (ui64 > 0 && ui64 <= 2147483647)
161 return "invalid positional specification";
164 width_index = index++;
167 else if (parse_unsigned_integer (&p, &ui64))
169 if (ui64 <= 2147483647)
172 return "invalid field width specification";
178 use_precision =
true;
184 if (parse_positional (&p, &ui64))
186 if (ui64 > 0 && ui64 <= 2147483647)
187 precision_index = ui64;
189 return "invalid positional specification";
192 precision_index = index++;
194 else if (parse_unsigned_integer (&p, &ui64))
196 if (ui64 <= 2147483647)
199 return "invalid precision specification";
202 const char *modifiers =
"hlLjztqZ";
203 while (
strchr (modifiers, *p))
206 const char *conversion_chars =
"dioucCspmXxEeFfGgAa%";
207 if (!
strchr (conversion_chars, *p))
208 return "missing conversion specifier";
209 if (value_index == 0 && !
strchr (
"m%", *p))
210 value_index = index++;
212 if (conversion ==
'C')
225 return render_value (N, args,
"",
int (0));
227 return render_value (N, args,
"", arg_as_ptr (N, args, value_index));
229 return render_value (N, args,
"", arg_as_chars (N, args, value_index));
230 case 'c':
case 'd':
case 'i':
case 'o':
case 'u':
case 'X':
case 'x':
231 return render_value (N, args,
"ll", arg_as_longlong (N, args, value_index));
232 case 'f':
case 'F':
case 'e':
case 'E':
case 'g':
case 'G':
case 'a':
case 'A':
233 return render_value (N, args,
"", arg_as_double (N, args, value_index));
250 if (!(nth && nth <= N))
254 return *p ? *p :
"(null)";
262 return (
void*) ptrdiff_t (arg_as_longlong (N, args, nth));
267 int32_t w = arg_as_longlong (N, args, nth);
269 return w < 0 ? std::abs (w + 1) : w;
272 arg_as_precision (
const size_t N,
const StringFormatArg *args,
size_t nth)
274 const int32_t precision = arg_as_longlong (N, args, nth);
278 arg_as_longlong (
const size_t N,
const StringFormatArg *args,
size_t nth)
290 arg_as_double (
const size_t N,
const StringFormatArg *args,
size_t nth)
302 render_value (
const size_t N,
const StringFormatArg *args,
const char *modifier,
Value value)
const
305 const int field_width = !use_width || !width_index ? this->field_width : arg_as_width (N, args, width_index);
306 const int field_precision = !use_precision || !precision_index ?
std::max (
uint32_t (0), precision) : arg_as_precision (N, args, precision_index);
315 if (zero_padding && !adjust_left &&
strchr (
"diouXx" "FfGgEeAa", conversion))
317 if (alternate_form &&
strchr (
"oXx" "FfGgEeAa", conversion))
319 if (locale_grouping &&
strchr (
"idu" "FfGg", conversion))
323 if (use_precision &&
strchr (
"sm" "diouXx" "FfGgEeAa", conversion))
327 format += conversion;
329 if (use_width && use_precision)
330 return system_string_printf (format.c_str(), field_width, field_precision, value);
331 else if (use_precision)
332 return system_string_printf (format.c_str(), field_precision, value);
334 return system_string_printf (format.c_str(), field_width, value);
336 return system_string_printf (format.c_str(), value);
370 fprintf (stderr,
"%sStringFormatter: %sWARNING:%s%s %s in directive %zu:%s %s\n", cyan, cred, crst, cyel, err, directive, crst, format);
372 fprintf (stderr,
"%sStringFormatter: %sWARNING:%s%s %s:%s %s\n", cyan, cred, crst, cyel, err, crst, format);