67 lines
1.9 KiB
C++
67 lines
1.9 KiB
C++
#include <string>
|
|
#include <sstream>
|
|
#include <stdarg.h>
|
|
#include "UsefulException.hpp"
|
|
#include "std.hpp"
|
|
|
|
std::string _format(const std::string& format_str, const size_t args_count, ...){
|
|
va_list vl;
|
|
va_start(vl, args_count);
|
|
std::stringstream ss;
|
|
|
|
for(size_t i = 0; i < format_str.length(); i++){
|
|
char c = format_str[i];
|
|
|
|
// format specifier
|
|
if(c == '%'){
|
|
c = format_str[++i];
|
|
bool l = false;
|
|
while(c == 'l'){
|
|
l = true;
|
|
c = format_str[++i];
|
|
}
|
|
|
|
switch(c){
|
|
case 'u':
|
|
if(l) ss<<(u64)va_arg(vl, u64);
|
|
else ss<<(u32)va_arg(vl, u32);
|
|
break;
|
|
case 'i':
|
|
case 'd':
|
|
if(l) ss<<(i64)va_arg(vl, i64);
|
|
else ss<<(i32)va_arg(vl, i32);
|
|
break;
|
|
case 'f':
|
|
// f32 is promoted to f64 when passed through '...'
|
|
ss<<(f64)va_arg(vl, f64);
|
|
break;
|
|
case 'p':
|
|
ss<<(void*)va_arg(vl, void*);
|
|
break;
|
|
case 'x':
|
|
if(l) ss<<std::hex<<(u64)va_arg(vl, u64);
|
|
else ss<<std::hex<<(u32)va_arg(vl, u32);
|
|
break;
|
|
case 's': {
|
|
const char* cptr = va_arg(vl,char*);
|
|
if(cptr != nullptr)
|
|
ss<<cptr;
|
|
else ss<<"<nullptr>";
|
|
break;
|
|
}
|
|
case 'c':
|
|
ss<<(char)va_arg(vl,int);
|
|
break;
|
|
default:
|
|
throw UsefulException("invalid format cpecifier");
|
|
}
|
|
}
|
|
|
|
// regular character
|
|
else ss<<c;
|
|
}
|
|
|
|
va_end(vl);
|
|
return ss.str();
|
|
}
|