small rectorings
This commit is contained in:
255
clib/printf.cpp
255
clib/printf.cpp
@@ -1,15 +1,16 @@
|
||||
#include "printf.h"
|
||||
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
|
||||
std::string mini_sprintf_format(bool left_align, bool sign, bool space_on_left, bool padding_by_zero, int width, int precision, int length, char specifier, const MlValue &value) {
|
||||
std::string
|
||||
mini_sprintf_format(bool left_align, bool sign, bool space_on_left, bool padding_by_zero, int width, int precision,
|
||||
int length, char specifier, const MlValue &value) {
|
||||
std::string s;
|
||||
std::ostringstream stream_str; // PERF simpler solution..without string stream
|
||||
std::ostringstream stream_str; // PERF simpler solution..without string stream
|
||||
bool is_positive = false;
|
||||
|
||||
if (specifier == 's') {
|
||||
@@ -21,13 +22,13 @@ std::string mini_sprintf_format(bool left_align, bool sign, bool space_on_left,
|
||||
}
|
||||
if (specifier == 'i' || specifier == 'd') {
|
||||
if (value.is_number()) {
|
||||
int ival = value.as_int();
|
||||
auto ival = value.as_int();
|
||||
is_positive = ival >= 0;
|
||||
|
||||
s = std::to_string(ival);
|
||||
} else if (value.is_string()) { // print ascii code of character
|
||||
if (value.as_string().size() > 0) {
|
||||
stream_str << (int)value.as_string()[0];
|
||||
} else if (value.is_string()) { // print ascii code of character
|
||||
if (!value.as_string().empty()) {
|
||||
stream_str << (int) value.as_string()[0];
|
||||
return stream_str.str();
|
||||
} else {
|
||||
// TODO handle empty string - error?
|
||||
@@ -88,96 +89,98 @@ std::string mini_sprintf(const std::string &format_str, const std::vector<MlValu
|
||||
|
||||
c1 = *si;
|
||||
switch (c1) {
|
||||
case '%':
|
||||
output_str += c1;
|
||||
break;
|
||||
case '-':
|
||||
case '+':
|
||||
case ' ':
|
||||
case '#':
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
case '.':
|
||||
case 'i':
|
||||
case 'd':
|
||||
case 'f':
|
||||
case 'c':
|
||||
case 's':
|
||||
bool left_align = false;
|
||||
bool sign = false;
|
||||
bool space_on_left = false;
|
||||
bool padding_by_zero = false;
|
||||
int width = -1;
|
||||
int precision = -1;
|
||||
int length = -1;
|
||||
// http://www.cplusplus.com/reference/cstdio/printf/
|
||||
// https://www.menie.org/georges/embedded/small_printf_source_code.html
|
||||
//
|
||||
// %[flags][width][.precision][length]specifier
|
||||
case '%':
|
||||
output_str += c1;
|
||||
break;
|
||||
case '-':
|
||||
case '+':
|
||||
case ' ':
|
||||
case '#':
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
case '.':
|
||||
case 'i':
|
||||
case 'd':
|
||||
case 'f':
|
||||
case 'c':
|
||||
case 's':
|
||||
bool left_align = false;
|
||||
bool sign = false;
|
||||
bool space_on_left = false;
|
||||
bool padding_by_zero = false;
|
||||
int width = -1;
|
||||
int precision = -1;
|
||||
int length = -1;
|
||||
// http://www.cplusplus.com/reference/cstdio/printf/
|
||||
// https://www.menie.org/georges/embedded/small_printf_source_code.html
|
||||
//
|
||||
// %[flags][width][.precision][length]specifier
|
||||
|
||||
// flags: - + \_ # 0
|
||||
while ((*si == '-' || *si == '+' || *si == ' ' || *si == '#' || *si == '0') && si < format_str.end()) {
|
||||
switch (*si) {
|
||||
case '-':
|
||||
left_align = true;
|
||||
break;
|
||||
case '+':
|
||||
sign = true;
|
||||
break;
|
||||
case ' ':
|
||||
space_on_left = true;
|
||||
break;
|
||||
case '#':
|
||||
break;
|
||||
case '0':
|
||||
padding_by_zero = true;
|
||||
left_align = true;
|
||||
break;
|
||||
};
|
||||
si++;
|
||||
}
|
||||
// width
|
||||
if (si >= format_str.end())
|
||||
return output_str; // invalid end of string
|
||||
while (*si >= '0' && *si <= '9' && si < format_str.end()) {
|
||||
if (width == -1) {
|
||||
width = 0;
|
||||
}
|
||||
width = width * 10 + (*si - '0');
|
||||
si++;
|
||||
}
|
||||
// precision
|
||||
if (si >= format_str.end())
|
||||
return output_str; // invalid end of string
|
||||
if (*si == '.') {
|
||||
precision = 0;
|
||||
if (++si >= format_str.end())
|
||||
return output_str; // invalid end of string
|
||||
while (*si >= '0' && *si <= '9' && si < format_str.end()) {
|
||||
precision = precision * 10 + (*si - '0');
|
||||
// flags: - + \_ # 0
|
||||
while ((*si == '-' || *si == '+' || *si == ' ' || *si == '#' || *si == '0') &&
|
||||
si < format_str.end()) {
|
||||
switch (*si) {
|
||||
case '-':
|
||||
left_align = true;
|
||||
break;
|
||||
case '+':
|
||||
sign = true;
|
||||
break;
|
||||
case ' ':
|
||||
space_on_left = true;
|
||||
break;
|
||||
case '#':
|
||||
break;
|
||||
case '0':
|
||||
padding_by_zero = true;
|
||||
left_align = true;
|
||||
break;
|
||||
}
|
||||
si++;
|
||||
}
|
||||
}
|
||||
// length
|
||||
// specifier
|
||||
if (si >= format_str.end())
|
||||
return output_str; // invalid end of string
|
||||
if (*si == 'i' || *si == 'd' || *si == 'f' || *si == 's' || *si == 'c') { // TODO more specifiers
|
||||
std::string s = mini_sprintf_format(left_align, sign, space_on_left, padding_by_zero, width, precision, length, *si, parameters[arg_position]);
|
||||
arg_position++;
|
||||
output_str += s;
|
||||
} else {
|
||||
output_str += "UNKNOWN FORMAT SPECIFIER";
|
||||
}
|
||||
};
|
||||
// width
|
||||
if (si >= format_str.end())
|
||||
return output_str; // invalid end of string
|
||||
while (*si >= '0' && *si <= '9' && si < format_str.end()) {
|
||||
if (width == -1) {
|
||||
width = 0;
|
||||
}
|
||||
width = width * 10 + (*si - '0');
|
||||
si++;
|
||||
}
|
||||
// precision
|
||||
if (si >= format_str.end())
|
||||
return output_str; // invalid end of string
|
||||
if (*si == '.') {
|
||||
precision = 0;
|
||||
if (++si >= format_str.end())
|
||||
return output_str; // invalid end of string
|
||||
while (*si >= '0' && *si <= '9' && si < format_str.end()) {
|
||||
precision = precision * 10 + (*si - '0');
|
||||
si++;
|
||||
}
|
||||
}
|
||||
// length
|
||||
// specifier
|
||||
if (si >= format_str.end())
|
||||
return output_str; // invalid end of string
|
||||
if (*si == 'i' || *si == 'd' || *si == 'f' || *si == 's' || *si == 'c') { // TODO more specifiers
|
||||
std::string s = mini_sprintf_format(left_align, sign, space_on_left, padding_by_zero, width,
|
||||
precision, length, *si, parameters[arg_position]);
|
||||
arg_position++;
|
||||
output_str += s;
|
||||
} else {
|
||||
output_str += "UNKNOWN FORMAT SPECIFIER";
|
||||
}
|
||||
}
|
||||
|
||||
// escaping sequences
|
||||
} else if (c == '\\') {
|
||||
@@ -187,38 +190,38 @@ std::string mini_sprintf(const std::string &format_str, const std::vector<MlValu
|
||||
|
||||
c1 = *si;
|
||||
switch (c1) {
|
||||
case 't':
|
||||
output_str += '\t';
|
||||
break;
|
||||
case 'r':
|
||||
output_str += '\r';
|
||||
break;
|
||||
case 'n':
|
||||
output_str += '\n';
|
||||
break;
|
||||
case 'x': // hex ie \x1b
|
||||
if (si + 2 >= format_str.end()) return output_str; // end of string, invalid hex constant
|
||||
buf.clear();
|
||||
buf.push_back(*(si + 1));
|
||||
buf.push_back(*(si + 2));
|
||||
output_str.push_back((char)std::strtol( &buf[0], 0, 16));
|
||||
si += 2;
|
||||
break;
|
||||
case '0': // octal ie "\033"
|
||||
if (si + 2 >= format_str.end()) return output_str; // end of string, invalid octal constant
|
||||
buf.clear();
|
||||
buf.push_back(*(si + 1));
|
||||
buf.push_back(*(si + 2));
|
||||
output_str.push_back((char)std::strtol( &buf[0], 0, 8));
|
||||
// TODO maybe octal constant has 3 bytes
|
||||
// if (si + 2 >= format_str.end()) return output_str; // end of string, invalid octal or hex constant
|
||||
// buf.push_back(*(si + 3));
|
||||
// si += 3;
|
||||
si += 2;
|
||||
break;
|
||||
default:
|
||||
output_str += c1;
|
||||
};
|
||||
case 't':
|
||||
output_str += '\t';
|
||||
break;
|
||||
case 'r':
|
||||
output_str += '\r';
|
||||
break;
|
||||
case 'n':
|
||||
output_str += '\n';
|
||||
break;
|
||||
case 'x': // hex ie \x1b
|
||||
if (si + 2 >= format_str.end()) return output_str; // end of string, invalid hex constant
|
||||
buf.clear();
|
||||
buf.push_back(*(si + 1));
|
||||
buf.push_back(*(si + 2));
|
||||
output_str.push_back((char) std::strtol(&buf[0], nullptr, 16));
|
||||
si += 2;
|
||||
break;
|
||||
case '0': // octal ie "\033"
|
||||
if (si + 2 >= format_str.end()) return output_str; // end of string, invalid octal constant
|
||||
buf.clear();
|
||||
buf.push_back(*(si + 1));
|
||||
buf.push_back(*(si + 2));
|
||||
output_str.push_back((char) std::strtol(&buf[0], nullptr, 8));
|
||||
// TODO maybe octal constant has 3 bytes
|
||||
// if (si + 2 >= format_str.end()) return output_str; // end of string, invalid octal or hex constant
|
||||
// buf.push_back(*(si + 3));
|
||||
// si += 3;
|
||||
si += 2;
|
||||
break;
|
||||
default:
|
||||
output_str += c1;
|
||||
}
|
||||
|
||||
// normal characters
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user