18#pragma warning(disable: 4996)
42static const char *
parse(
const char *f,
Spec &
s, va_list &ap)
44 for (
bool more =
true; more;) {
77 s.width = va_arg(ap,
int);
78 if (
s.width < 0) {
s.minus =
true;
s.width = -
s.width; }
81 while (*f >=
'0' && *f <=
'9') {
s.width =
s.width * 10 + (*f++ -
'0'); }
88 s.prec = va_arg(ap,
int);
89 if (
s.prec < 0)
s.prec = -1;
92 while (*f >=
'0' && *f <=
'9') {
s.prec =
s.prec * 10 + (*f++ -
'0'); }
140 if (
s.minus) f +=
'-';
141 if (
s.plus) f +=
'+';
142 if (
s.space) f +=
' ';
143 if (
s.hash) f +=
'#';
144 if (
s.zero) f +=
'0';
145 if (
s.quote) f +=
'\'';
146 if (
s.width > 0) f += std::to_string(
s.width);
147 if (
s.prec >= 0) { f +=
'.'; f += std::to_string(
s.prec); }
153template<
typename Fill>
156 int sz = std::max(
hint, 64);
157 std::vector<char> buf(sz);
158 int needed = fill(buf.data(), sz);
159 if (needed < 0)
return {};
161 buf.resize(needed + 1);
162 fill(buf.data(), needed + 1);
164 return std::string(buf.data());
168 return std::max({
s.width,
s.prec, 0 }) + 80;
176 val = (
signed char)va_arg(ap,
int);
179 val = (short)va_arg(ap,
int);
182 val = va_arg(ap,
long);
185 val = va_arg(ap,
long long);
188 val = (
long long)va_arg(ap, std::ptrdiff_t);
191 val = va_arg(ap, std::ptrdiff_t);
194 val = (
long long)va_arg(ap, std::intmax_t);
197 val = va_arg(ap,
int);
202 return std::snprintf(b, n, f.c_str(), val);
208 unsigned long long val;
211 val = (
unsigned char)va_arg(ap,
unsigned int);
214 val = (
unsigned short)va_arg(ap,
unsigned int);
217 val = va_arg(ap,
unsigned long);
220 val = va_arg(ap,
unsigned long long);
223 val = (
unsigned long long) va_arg(ap, std::size_t);
226 val = (
unsigned long long)(std::ptrdiff_t)va_arg(ap, std::ptrdiff_t);
229 val = (
unsigned long long) va_arg(ap, std::uintmax_t);
232 val = va_arg(ap,
unsigned int);
237 return std::snprintf(b, n, f.c_str(), val);
244 long double val = va_arg(ap,
long double);
247 return std::snprintf(b, n, f.c_str(), val);
250 double val = va_arg(ap,
double);
253 return std::snprintf(b, n, f.c_str(), val);
260 char c = (char)va_arg(ap,
int);
261 int pad =
s.width - 1;
263 if (!
s.minus && pad > 0) out.append(pad,
' ');
265 if (
s.minus && pad > 0) out.append(pad,
' ');
271 const char *str = va_arg(ap,
const char *);
272 if (!str) str =
"(null)";
274 std::size_t len = (
s.prec >= 0)
275 ? ::strnlen(str, (std::size_t)
s.prec)
278 int pad =
s.width - (int)len;
280 out.reserve(len + std::max(pad, 0));
281 if (!
s.minus && pad > 0) out.append(pad,
' ');
282 out.append(str, len);
283 if (
s.minus && pad > 0) out.append(pad,
' ');
289 void *val = va_arg(ap,
void *);
291 if (
s.minus) f +=
'-';
292 if (
s.width > 0) f += std::to_string(
s.width);
295 return std::snprintf(b, n, f.c_str(), val);
358 result += ::strerror(errno);
362 (void)va_arg(ap,
int *);
368 if (
s.conv) result +=
s.conv;
379inline std::string
vformat(
const char *fmt, va_list ap)
384inline std::string
format(
const char *fmt, ...)
393inline int vfprintf(std::ostream &os,
const char *fmt, va_list ap)
396 os.write(
s.data(), (std::streamsize)
s.size());
398 return (
int)
s.size();
401inline int fprintf(std::ostream &os,
const char *fmt, ...)
414 int r =
vfprintf(std::cout, fmt, ap);
419inline std::string
str_format_v(
const char *fmt,
const std::vector<Phasor::Value> &args)
443 for (
bool more =
true; more;) {
475 while (*f >=
'0' && *f <=
'9')
s.width =
s.width * 10 + (*f++ -
'0');
480 while (*f >=
'0' && *f <=
'9')
s.prec =
s.prec * 10 + (*f++ -
'0');
517 if (
s.conv ==
'm') { result += ::strerror(errno);
continue; }
518 if (
s.conv ==
'n') {
continue; }
520 if (argIndex >= args.size())
continue;
527 case 'u':
case 'o':
case 'x':
case 'X': {
534 ival = val.
asBool() ? 1LL : 0LL;
537 ival = (
long long)val.
asFloat();
543 if (
s.conv ==
'd' ||
s.conv ==
'i') {
545 return std::snprintf(b, n, fmtStr.c_str(), ival);
548 unsigned long long uval = (
unsigned long long)ival;
550 return std::snprintf(b, n, fmtStr.c_str(), uval);
556 case 'f':
case 'F':
case 'e':
case 'E':
557 case 'g':
case 'G':
case 'a':
case 'A': {
564 dval = (double)val.
asInt();
567 dval = val.
asBool() ? 1.0 : 0.0;
574 return std::snprintf(b, n, fmtStr.c_str(), dval);
588 str = val.
asBool() ?
"true" :
"false";
598 std::size_t len = (
s.prec >= 0)
599 ? std::min((std::size_t)
s.prec, str.size())
601 int pad =
s.width - (int)len;
602 if (!
s.minus && pad > 0) result.append(pad,
' ');
603 result.append(str.data(), len);
604 if (
s.minus && pad > 0) result.append(pad,
' ');
612 c = (char)val.
asInt();
615 c = val.
asBool() ?
'\x01' :
'\x00';
620 int pad =
s.width - 1;
621 if (!
s.minus && pad > 0) result.append(pad,
' ');
623 if (
s.minus && pad > 0) result.append(pad,
' ');
628 const void *ptr =
static_cast<const void *
>(&val);
629 std::string fmtStr =
"%";
630 if (
s.minus) fmtStr +=
'-';
631 if (
s.width > 0) fmtStr += std::to_string(
s.width);
634 return std::snprintf(b, n, fmtStr.c_str(), ptr);
641 if (
s.conv) result +=
s.conv;
A value in the Phasor VM.
PhsString asString() const noexcept
Get the value as a Small String.
ValueType getType() const noexcept
Get the type of the value.
f64 asFloat() const noexcept
Get the value as a f64.
i64 asInt() const noexcept
Get the value as an integer.
bool asBool() const noexcept
Get the value as a boolean.
std::string toString() const noexcept
Convert to string for printing.
ValueType
Runtime value types for the VM.