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));
231 return render_value (N, args,
"", arg_as_char (N, args, value_index));
232 case 'd':
case 'i':
case 'o':
case 'u':
case 'X':
case 'x':
233 return render_value (N, args,
"ll", arg_as_longlong (N, args, value_index));
234 case 'f':
case 'F':
case 'e':
case 'E':
case 'g':
case 'G':
case 'a':
case 'A':
235 return render_value (N, args,
"", arg_as_double (N, args, value_index));
252 if (!(nth && nth <= N))
256 return *p ? *p :
"(null)";
264 return (
void*) ptrdiff_t (arg_as_longlong (N, args, nth));
269 int32_t w = arg_as_longlong (N, args, nth);
271 return w < 0 ? std::abs (w + 1) : w;
274 arg_as_precision (
const size_t N,
const StringFormatArg *args,
size_t nth)
276 const int32_t precision = arg_as_longlong (N, args, nth);
282 return arg_as_longlong (N, args, nth);
285 arg_as_longlong (
const size_t N,
const StringFormatArg *args,
size_t nth)
297 arg_as_double (
const size_t N,
const StringFormatArg *args,
size_t nth)
309 render_value (
const size_t N,
const StringFormatArg *args,
const char *modifier,
Value value)
const
312 const int field_width = !use_width || !width_index ? this->field_width : arg_as_width (N, args, width_index);
313 const int field_precision = !use_precision || !precision_index ?
std::max (
uint32_t (0), precision) : arg_as_precision (N, args, precision_index);
322 if (zero_padding && !adjust_left &&
strchr (
"diouXx" "FfGgEeAa", conversion))
324 if (alternate_form &&
strchr (
"oXx" "FfGgEeAa", conversion))
326 if (locale_grouping &&
strchr (
"idu" "FfGg", conversion))
330 if (use_precision &&
strchr (
"sm" "diouXx" "FfGgEeAa", conversion))
334 format += conversion;
336 if (use_width && use_precision)
337 return system_string_printf (format.c_str(), field_width, field_precision, value);
338 else if (use_precision)
339 return system_string_printf (format.c_str(), field_precision, value);
341 return system_string_printf (format.c_str(), field_width, value);
343 return system_string_printf (format.c_str(), value);
377 fprintf (stderr,
"%sStringFormatter: %sWARNING:%s%s %s in directive %zu:%s %s\n", cyan, cred, crst, cyel, err, directive, crst, format);