#include "internal.hpp"
namespace CaDiCaL {
void Format::enlarge () {
char *old = buffer;
buffer = new char[size = size ? 2 * size : 1];
memcpy (buffer, old, count);
delete[] old;
}
inline void Format::push_char (char ch) {
if (size == count)
enlarge ();
buffer[count++] = ch;
}
void Format::push_string (const char *s) {
char ch;
while ((ch = *s++))
push_char (ch);
}
void Format::push_int (int d) {
char tmp[16];
snprintf (tmp, sizeof tmp, "%d", d);
push_string (tmp);
}
void Format::push_uint64 (uint64_t u) {
char tmp[16];
snprintf (tmp, sizeof tmp, "%" PRIu64, u);
push_string (tmp);
}
static bool match_format (const char *&str, const char *pattern) {
assert (pattern);
const char *p = str;
const char *q = pattern;
while (*q)
if (*q++ != *p++)
return false;
str = p;
return true;
}
const char *Format::add (const char *fmt, va_list &ap) {
const char *p = fmt;
char ch;
while ((ch = *p++)) {
if (ch != '%')
push_char (ch);
else if (*p == 'c')
push_char (va_arg (ap, int)), p++;
else if (*p == 'd')
push_int (va_arg (ap, int)), p++;
else if (*p == 's')
push_string (va_arg (ap, const char *)), p++;
else if (match_format (p, PRIu64))
push_uint64 (va_arg (ap, uint64_t));
else {
push_char ('%');
push_char (*p);
break;
} }
push_char (0);
count--; return buffer;
}
const char *Format::init (const char *fmt, ...) {
count = 0;
va_list ap;
va_start (ap, fmt);
const char *res = add (fmt, ap);
va_end (ap);
return res;
}
const char *Format::append (const char *fmt, ...) {
va_list ap;
va_start (ap, fmt);
const char *res = add (fmt, ap);
va_end (ap);
return res;
}
}