mirror of
https://github.com/esp8266/Arduino.git
synced 2025-07-29 05:21:37 +03:00
Migrate from astyle to clang-format (#8464)
This commit is contained in:
committed by
Max Prokhorov
parent
46190b61f1
commit
19b7a29720
@ -7,29 +7,30 @@ namespace bs
|
||||
class ArduinoIOHelper
|
||||
{
|
||||
public:
|
||||
ArduinoIOHelper(Stream& stream) : m_stream(stream)
|
||||
{
|
||||
}
|
||||
ArduinoIOHelper(Stream& stream) : m_stream(stream) { }
|
||||
|
||||
size_t printf(const char *format, ...)
|
||||
size_t printf(const char* format, ...)
|
||||
{
|
||||
va_list arg;
|
||||
va_start(arg, format);
|
||||
char temp[128];
|
||||
char* buffer = temp;
|
||||
size_t len = vsnprintf(temp, sizeof(temp), format, arg);
|
||||
char temp[128];
|
||||
char* buffer = temp;
|
||||
size_t len = vsnprintf(temp, sizeof(temp), format, arg);
|
||||
va_end(arg);
|
||||
if (len > sizeof(temp) - 1) {
|
||||
if (len > sizeof(temp) - 1)
|
||||
{
|
||||
buffer = new char[len + 1];
|
||||
if (!buffer) {
|
||||
if (!buffer)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
va_start(arg, format);
|
||||
ets_vsnprintf(buffer, len + 1, format, arg);
|
||||
va_end(arg);
|
||||
}
|
||||
len = m_stream.write((const uint8_t*) buffer, len);
|
||||
if (buffer != temp) {
|
||||
len = m_stream.write((const uint8_t*)buffer, len);
|
||||
if (buffer != temp)
|
||||
{
|
||||
delete[] buffer;
|
||||
}
|
||||
return len;
|
||||
@ -40,16 +41,20 @@ public:
|
||||
size_t len = 0;
|
||||
// Can't use Stream::readBytesUntil here because it can't tell the
|
||||
// difference between timing out and receiving the terminator.
|
||||
while (len < dest_size - 1) {
|
||||
while (len < dest_size - 1)
|
||||
{
|
||||
int c = m_stream.read();
|
||||
if (c < 0) {
|
||||
if (c < 0)
|
||||
{
|
||||
delay(1);
|
||||
continue;
|
||||
}
|
||||
if (c == '\r') {
|
||||
if (c == '\r')
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (c == '\n') {
|
||||
if (c == '\n')
|
||||
{
|
||||
dest[len] = 0;
|
||||
break;
|
||||
}
|
||||
@ -64,10 +69,11 @@ protected:
|
||||
|
||||
typedef ArduinoIOHelper IOHelper;
|
||||
|
||||
inline void fatal() {
|
||||
inline void fatal()
|
||||
{
|
||||
ESP.restart();
|
||||
}
|
||||
|
||||
} // namespace bs
|
||||
} // namespace bs
|
||||
|
||||
#endif //BS_ARDUINO_H
|
||||
#endif // BS_ARDUINO_H
|
||||
|
@ -18,134 +18,162 @@ namespace protocol
|
||||
|
||||
#define SS_FLAG_ESCAPE 0x8
|
||||
|
||||
typedef enum {
|
||||
/* parsing the space between arguments */
|
||||
SS_SPACE = 0x0,
|
||||
/* parsing an argument which isn't quoted */
|
||||
SS_ARG = 0x1,
|
||||
/* parsing a quoted argument */
|
||||
SS_QUOTED_ARG = 0x2,
|
||||
/* parsing an escape sequence within unquoted argument */
|
||||
SS_ARG_ESCAPED = SS_ARG | SS_FLAG_ESCAPE,
|
||||
/* parsing an escape sequence within a quoted argument */
|
||||
SS_QUOTED_ARG_ESCAPED = SS_QUOTED_ARG | SS_FLAG_ESCAPE,
|
||||
} split_state_t;
|
||||
typedef enum
|
||||
{
|
||||
/* parsing the space between arguments */
|
||||
SS_SPACE = 0x0,
|
||||
/* parsing an argument which isn't quoted */
|
||||
SS_ARG = 0x1,
|
||||
/* parsing a quoted argument */
|
||||
SS_QUOTED_ARG = 0x2,
|
||||
/* parsing an escape sequence within unquoted argument */
|
||||
SS_ARG_ESCAPED = SS_ARG | SS_FLAG_ESCAPE,
|
||||
/* parsing an escape sequence within a quoted argument */
|
||||
SS_QUOTED_ARG_ESCAPED = SS_QUOTED_ARG | SS_FLAG_ESCAPE,
|
||||
} split_state_t;
|
||||
|
||||
/* helper macro, called when done with an argument */
|
||||
#define END_ARG() do { \
|
||||
char_out = 0; \
|
||||
argv[argc++] = next_arg_start; \
|
||||
state = SS_SPACE; \
|
||||
} while(0);
|
||||
#define END_ARG() \
|
||||
do \
|
||||
{ \
|
||||
char_out = 0; \
|
||||
argv[argc++] = next_arg_start; \
|
||||
state = SS_SPACE; \
|
||||
} while (0);
|
||||
|
||||
/**
|
||||
* @brief Split command line into arguments in place
|
||||
*
|
||||
* - This function finds whitespace-separated arguments in the given input line.
|
||||
*
|
||||
* 'abc def 1 20 .3' -> [ 'abc', 'def', '1', '20', '.3' ]
|
||||
*
|
||||
* - Argument which include spaces may be surrounded with quotes. In this case
|
||||
* spaces are preserved and quotes are stripped.
|
||||
*
|
||||
* 'abc "123 456" def' -> [ 'abc', '123 456', 'def' ]
|
||||
*
|
||||
* - Escape sequences may be used to produce backslash, double quote, and space:
|
||||
*
|
||||
* 'a\ b\\c\"' -> [ 'a b\c"' ]
|
||||
*
|
||||
* Pointers to at most argv_size - 1 arguments are returned in argv array.
|
||||
* The pointer after the last one (i.e. argv[argc]) is set to NULL.
|
||||
*
|
||||
* @param line pointer to buffer to parse; it is modified in place
|
||||
* @param argv array where the pointers to arguments are written
|
||||
* @param argv_size number of elements in argv_array (max. number of arguments will be argv_size
|
||||
* - 1)
|
||||
* @return number of arguments found (argc)
|
||||
*/
|
||||
inline size_t split_args(char* line, char** argv, size_t argv_size)
|
||||
{
|
||||
const int QUOTE = '"';
|
||||
const int ESCAPE = '\\';
|
||||
const int SPACE = ' ';
|
||||
split_state_t state = SS_SPACE;
|
||||
size_t argc = 0;
|
||||
char* next_arg_start = line;
|
||||
char* out_ptr = line;
|
||||
for (char* in_ptr = line; argc < argv_size - 1; ++in_ptr)
|
||||
{
|
||||
int char_in = (unsigned char)*in_ptr;
|
||||
if (char_in == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
int char_out = -1;
|
||||
|
||||
/**
|
||||
* @brief Split command line into arguments in place
|
||||
*
|
||||
* - This function finds whitespace-separated arguments in the given input line.
|
||||
*
|
||||
* 'abc def 1 20 .3' -> [ 'abc', 'def', '1', '20', '.3' ]
|
||||
*
|
||||
* - Argument which include spaces may be surrounded with quotes. In this case
|
||||
* spaces are preserved and quotes are stripped.
|
||||
*
|
||||
* 'abc "123 456" def' -> [ 'abc', '123 456', 'def' ]
|
||||
*
|
||||
* - Escape sequences may be used to produce backslash, double quote, and space:
|
||||
*
|
||||
* 'a\ b\\c\"' -> [ 'a b\c"' ]
|
||||
*
|
||||
* Pointers to at most argv_size - 1 arguments are returned in argv array.
|
||||
* The pointer after the last one (i.e. argv[argc]) is set to NULL.
|
||||
*
|
||||
* @param line pointer to buffer to parse; it is modified in place
|
||||
* @param argv array where the pointers to arguments are written
|
||||
* @param argv_size number of elements in argv_array (max. number of arguments will be argv_size - 1)
|
||||
* @return number of arguments found (argc)
|
||||
*/
|
||||
inline size_t split_args(char *line, char **argv, size_t argv_size)
|
||||
{
|
||||
const int QUOTE = '"';
|
||||
const int ESCAPE = '\\';
|
||||
const int SPACE = ' ';
|
||||
split_state_t state = SS_SPACE;
|
||||
size_t argc = 0;
|
||||
char *next_arg_start = line;
|
||||
char *out_ptr = line;
|
||||
for (char *in_ptr = line; argc < argv_size - 1; ++in_ptr) {
|
||||
int char_in = (unsigned char) *in_ptr;
|
||||
if (char_in == 0) {
|
||||
break;
|
||||
switch (state)
|
||||
{
|
||||
case SS_SPACE:
|
||||
if (char_in == SPACE)
|
||||
{
|
||||
/* skip space */
|
||||
}
|
||||
else if (char_in == QUOTE)
|
||||
{
|
||||
next_arg_start = out_ptr;
|
||||
state = SS_QUOTED_ARG;
|
||||
}
|
||||
else if (char_in == ESCAPE)
|
||||
{
|
||||
next_arg_start = out_ptr;
|
||||
state = SS_ARG_ESCAPED;
|
||||
}
|
||||
else
|
||||
{
|
||||
next_arg_start = out_ptr;
|
||||
state = SS_ARG;
|
||||
char_out = char_in;
|
||||
}
|
||||
break;
|
||||
|
||||
case SS_QUOTED_ARG:
|
||||
if (char_in == QUOTE)
|
||||
{
|
||||
END_ARG();
|
||||
}
|
||||
else if (char_in == ESCAPE)
|
||||
{
|
||||
state = SS_QUOTED_ARG_ESCAPED;
|
||||
}
|
||||
else
|
||||
{
|
||||
char_out = char_in;
|
||||
}
|
||||
break;
|
||||
|
||||
case SS_ARG_ESCAPED:
|
||||
case SS_QUOTED_ARG_ESCAPED:
|
||||
if (char_in == ESCAPE || char_in == QUOTE || char_in == SPACE)
|
||||
{
|
||||
char_out = char_in;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* unrecognized escape character, skip */
|
||||
}
|
||||
state = (split_state_t)(state & (~SS_FLAG_ESCAPE));
|
||||
break;
|
||||
|
||||
case SS_ARG:
|
||||
if (char_in == SPACE)
|
||||
{
|
||||
END_ARG();
|
||||
}
|
||||
else if (char_in == ESCAPE)
|
||||
{
|
||||
state = SS_ARG_ESCAPED;
|
||||
}
|
||||
else
|
||||
{
|
||||
char_out = char_in;
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* need to output anything? */
|
||||
if (char_out >= 0)
|
||||
{
|
||||
*out_ptr = char_out;
|
||||
++out_ptr;
|
||||
}
|
||||
}
|
||||
int char_out = -1;
|
||||
|
||||
switch (state) {
|
||||
case SS_SPACE:
|
||||
if (char_in == SPACE) {
|
||||
/* skip space */
|
||||
} else if (char_in == QUOTE) {
|
||||
next_arg_start = out_ptr;
|
||||
state = SS_QUOTED_ARG;
|
||||
} else if (char_in == ESCAPE) {
|
||||
next_arg_start = out_ptr;
|
||||
state = SS_ARG_ESCAPED;
|
||||
} else {
|
||||
next_arg_start = out_ptr;
|
||||
state = SS_ARG;
|
||||
char_out = char_in;
|
||||
}
|
||||
break;
|
||||
|
||||
case SS_QUOTED_ARG:
|
||||
if (char_in == QUOTE) {
|
||||
END_ARG();
|
||||
} else if (char_in == ESCAPE) {
|
||||
state = SS_QUOTED_ARG_ESCAPED;
|
||||
} else {
|
||||
char_out = char_in;
|
||||
}
|
||||
break;
|
||||
|
||||
case SS_ARG_ESCAPED:
|
||||
case SS_QUOTED_ARG_ESCAPED:
|
||||
if (char_in == ESCAPE || char_in == QUOTE || char_in == SPACE) {
|
||||
char_out = char_in;
|
||||
} else {
|
||||
/* unrecognized escape character, skip */
|
||||
}
|
||||
state = (split_state_t) (state & (~SS_FLAG_ESCAPE));
|
||||
break;
|
||||
|
||||
case SS_ARG:
|
||||
if (char_in == SPACE) {
|
||||
END_ARG();
|
||||
} else if (char_in == ESCAPE) {
|
||||
state = SS_ARG_ESCAPED;
|
||||
} else {
|
||||
char_out = char_in;
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* need to output anything? */
|
||||
if (char_out >= 0) {
|
||||
*out_ptr = char_out;
|
||||
++out_ptr;
|
||||
/* make sure the final argument is terminated */
|
||||
*out_ptr = 0;
|
||||
/* finalize the last argument */
|
||||
if (state != SS_SPACE && argc < argv_size - 1)
|
||||
{
|
||||
argv[argc++] = next_arg_start;
|
||||
}
|
||||
/* add a NULL at the end of argv */
|
||||
argv[argc] = NULL;
|
||||
|
||||
return argc;
|
||||
}
|
||||
/* make sure the final argument is terminated */
|
||||
*out_ptr = 0;
|
||||
/* finalize the last argument */
|
||||
if (state != SS_SPACE && argc < argv_size - 1) {
|
||||
argv[argc++] = next_arg_start;
|
||||
}
|
||||
/* add a NULL at the end of argv */
|
||||
argv[argc] = NULL;
|
||||
|
||||
return argc;
|
||||
}
|
||||
} // namespace protocol
|
||||
|
||||
} // namespace bs
|
||||
} // namespace bs
|
||||
|
||||
} // namespace protocol
|
||||
|
||||
#endif //BS_ARGS_H
|
||||
#endif // BS_ARGS_H
|
||||
|
@ -11,108 +11,120 @@ namespace bs
|
||||
{
|
||||
namespace protocol
|
||||
{
|
||||
template<typename IO>
|
||||
void output_test_start(IO& io, const char* file, size_t line, const char* name, const char* desc)
|
||||
{
|
||||
io.printf(BS_LINE_PREFIX "start file=\"%s\" line=%d name=\"%s\" desc=\"%s\"\n", file, line, name, desc);
|
||||
}
|
||||
|
||||
template<typename IO>
|
||||
void output_check_failure(IO& io, size_t line)
|
||||
{
|
||||
io.printf(BS_LINE_PREFIX "check_failure line=%d\n", line);
|
||||
}
|
||||
|
||||
template<typename IO>
|
||||
void output_test_end(IO& io, bool success, size_t checks, size_t failed_checks, size_t line=0)
|
||||
{
|
||||
io.printf(BS_LINE_PREFIX "end line=%d result=%d checks=%d failed_checks=%d\n", line, success, checks, failed_checks);
|
||||
}
|
||||
|
||||
template<typename IO>
|
||||
void output_menu_begin(IO& io)
|
||||
{
|
||||
io.printf(BS_LINE_PREFIX "menu_begin\n");
|
||||
}
|
||||
|
||||
template<typename IO>
|
||||
void output_menu_item(IO& io, int index, const char* name, const char* desc)
|
||||
{
|
||||
io.printf(BS_LINE_PREFIX "item id=%d name=\"%s\" desc=\"%s\"\n", index, name, desc);
|
||||
}
|
||||
|
||||
template<typename IO>
|
||||
void output_menu_end(IO& io)
|
||||
{
|
||||
io.printf(BS_LINE_PREFIX "menu_end\n");
|
||||
}
|
||||
|
||||
template<typename IO>
|
||||
void output_setenv_result(IO& io, const char* key, const char* value)
|
||||
{
|
||||
io.printf(BS_LINE_PREFIX "setenv key=\"%s\" value=\"%s\"\n", key, value);
|
||||
}
|
||||
|
||||
template<typename IO>
|
||||
void output_getenv_result(IO& io, const char* key, const char* value)
|
||||
{
|
||||
(void) key;
|
||||
io.printf(BS_LINE_PREFIX "getenv value=\"%s\"\n", value);
|
||||
}
|
||||
|
||||
template<typename IO>
|
||||
void output_pretest_result(IO& io, bool res)
|
||||
{
|
||||
io.printf(BS_LINE_PREFIX "pretest result=%d\n", res?1:0);
|
||||
}
|
||||
|
||||
template<typename IO>
|
||||
bool input_handle(IO& io, char* line_buf, size_t line_buf_size, int& test_num)
|
||||
{
|
||||
int cb_read = io.read_line(line_buf, line_buf_size);
|
||||
if (cb_read == 0 || line_buf[0] == '\n') {
|
||||
return false;
|
||||
template<typename IO>
|
||||
void output_test_start(IO& io, const char* file, size_t line, const char* name,
|
||||
const char* desc)
|
||||
{
|
||||
io.printf(BS_LINE_PREFIX "start file=\"%s\" line=%d name=\"%s\" desc=\"%s\"\n", file, line,
|
||||
name, desc);
|
||||
}
|
||||
char* argv[4];
|
||||
size_t argc = split_args(line_buf, argv, sizeof(argv)/sizeof(argv[0]));
|
||||
if (argc == 0) {
|
||||
return false;
|
||||
|
||||
template<typename IO>
|
||||
void output_check_failure(IO& io, size_t line)
|
||||
{
|
||||
io.printf(BS_LINE_PREFIX "check_failure line=%d\n", line);
|
||||
}
|
||||
if (strcmp(argv[0], "setenv") == 0) {
|
||||
if (argc != 3) {
|
||||
|
||||
template<typename IO>
|
||||
void output_test_end(IO& io, bool success, size_t checks, size_t failed_checks, size_t line = 0)
|
||||
{
|
||||
io.printf(BS_LINE_PREFIX "end line=%d result=%d checks=%d failed_checks=%d\n", line,
|
||||
success, checks, failed_checks);
|
||||
}
|
||||
|
||||
template<typename IO>
|
||||
void output_menu_begin(IO& io)
|
||||
{
|
||||
io.printf(BS_LINE_PREFIX "menu_begin\n");
|
||||
}
|
||||
|
||||
template<typename IO>
|
||||
void output_menu_item(IO& io, int index, const char* name, const char* desc)
|
||||
{
|
||||
io.printf(BS_LINE_PREFIX "item id=%d name=\"%s\" desc=\"%s\"\n", index, name, desc);
|
||||
}
|
||||
|
||||
template<typename IO>
|
||||
void output_menu_end(IO& io)
|
||||
{
|
||||
io.printf(BS_LINE_PREFIX "menu_end\n");
|
||||
}
|
||||
|
||||
template<typename IO>
|
||||
void output_setenv_result(IO& io, const char* key, const char* value)
|
||||
{
|
||||
io.printf(BS_LINE_PREFIX "setenv key=\"%s\" value=\"%s\"\n", key, value);
|
||||
}
|
||||
|
||||
template<typename IO>
|
||||
void output_getenv_result(IO& io, const char* key, const char* value)
|
||||
{
|
||||
(void)key;
|
||||
io.printf(BS_LINE_PREFIX "getenv value=\"%s\"\n", value);
|
||||
}
|
||||
|
||||
template<typename IO>
|
||||
void output_pretest_result(IO& io, bool res)
|
||||
{
|
||||
io.printf(BS_LINE_PREFIX "pretest result=%d\n", res ? 1 : 0);
|
||||
}
|
||||
|
||||
template<typename IO>
|
||||
bool input_handle(IO& io, char* line_buf, size_t line_buf_size, int& test_num)
|
||||
{
|
||||
int cb_read = io.read_line(line_buf, line_buf_size);
|
||||
if (cb_read == 0 || line_buf[0] == '\n')
|
||||
{
|
||||
return false;
|
||||
}
|
||||
setenv(argv[1], argv[2], 1);
|
||||
output_setenv_result(io, argv[1], argv[2]);
|
||||
test_num = -1;
|
||||
return false; /* we didn't get the test number yet, so return false */
|
||||
}
|
||||
if (strcmp(argv[0], "getenv") == 0) {
|
||||
if (argc != 2) {
|
||||
char* argv[4];
|
||||
size_t argc = split_args(line_buf, argv, sizeof(argv) / sizeof(argv[0]));
|
||||
if (argc == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
const char* value = getenv(argv[1]);
|
||||
output_getenv_result(io, argv[1], (value != NULL) ? value : "");
|
||||
return false;
|
||||
}
|
||||
if (strcmp(argv[0], "pretest") == 0) {
|
||||
if (argc != 1) {
|
||||
if (strcmp(argv[0], "setenv") == 0)
|
||||
{
|
||||
if (argc != 3)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
setenv(argv[1], argv[2], 1);
|
||||
output_setenv_result(io, argv[1], argv[2]);
|
||||
test_num = -1;
|
||||
return false; /* we didn't get the test number yet, so return false */
|
||||
}
|
||||
if (strcmp(argv[0], "getenv") == 0)
|
||||
{
|
||||
if (argc != 2)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
const char* value = getenv(argv[1]);
|
||||
output_getenv_result(io, argv[1], (value != NULL) ? value : "");
|
||||
return false;
|
||||
}
|
||||
bool res = ::pretest();
|
||||
output_pretest_result(io, res);
|
||||
return false;
|
||||
if (strcmp(argv[0], "pretest") == 0)
|
||||
{
|
||||
if (argc != 1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
bool res = ::pretest();
|
||||
output_pretest_result(io, res);
|
||||
return false;
|
||||
}
|
||||
/* not one of the commands, try to parse as test number */
|
||||
char* endptr;
|
||||
test_num = (int)strtol(argv[0], &endptr, 10);
|
||||
if (endptr != argv[0] + strlen(argv[0]))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/* not one of the commands, try to parse as test number */
|
||||
char* endptr;
|
||||
test_num = (int) strtol(argv[0], &endptr, 10);
|
||||
if (endptr != argv[0] + strlen(argv[0])) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // ::protocol
|
||||
} // ::bs
|
||||
} // namespace protocol
|
||||
} // namespace bs
|
||||
|
||||
#endif //BS_PROTOCOL_H
|
||||
#endif // BS_PROTOCOL_H
|
||||
|
@ -9,11 +9,9 @@ namespace bs
|
||||
class StdIOHelper
|
||||
{
|
||||
public:
|
||||
StdIOHelper()
|
||||
{
|
||||
}
|
||||
StdIOHelper() { }
|
||||
|
||||
size_t printf(const char *format, ...)
|
||||
size_t printf(const char* format, ...)
|
||||
{
|
||||
va_list arg;
|
||||
va_start(arg, format);
|
||||
@ -25,11 +23,13 @@ public:
|
||||
size_t read_line(char* dest, size_t dest_size)
|
||||
{
|
||||
char* res = fgets(dest, dest_size, stdin);
|
||||
if (res == NULL) {
|
||||
if (res == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
size_t len = strlen(dest);
|
||||
if (dest[len - 1] == '\n') {
|
||||
if (dest[len - 1] == '\n')
|
||||
{
|
||||
dest[len - 1] = 0;
|
||||
len--;
|
||||
}
|
||||
@ -39,10 +39,11 @@ public:
|
||||
|
||||
typedef StdIOHelper IOHelper;
|
||||
|
||||
inline void fatal() {
|
||||
inline void fatal()
|
||||
{
|
||||
throw std::runtime_error("fatal error");
|
||||
}
|
||||
|
||||
} // namespace bs
|
||||
} // namespace bs
|
||||
|
||||
#endif //BS_STDIO_H
|
||||
#endif // BS_STDIO_H
|
||||
|
@ -20,15 +20,18 @@
|
||||
|
||||
namespace bs
|
||||
{
|
||||
typedef void(*test_case_func_t)();
|
||||
typedef void (*test_case_func_t)();
|
||||
|
||||
class TestCase
|
||||
{
|
||||
public:
|
||||
TestCase(TestCase* prev, test_case_func_t func, const char* file, size_t line, const char* name, const char* desc)
|
||||
: m_func(func), m_file(file), m_line(line), m_name(name), m_desc(desc)
|
||||
TestCase(TestCase* prev, test_case_func_t func, const char* file, size_t line, const char* name,
|
||||
const char* desc) :
|
||||
m_func(func),
|
||||
m_file(file), m_line(line), m_name(name), m_desc(desc)
|
||||
{
|
||||
if (prev) {
|
||||
if (prev)
|
||||
{
|
||||
prev->m_next = this;
|
||||
}
|
||||
}
|
||||
@ -60,36 +63,40 @@ public:
|
||||
|
||||
const char* desc() const
|
||||
{
|
||||
return (m_desc)?m_desc:"";
|
||||
return (m_desc) ? m_desc : "";
|
||||
}
|
||||
|
||||
protected:
|
||||
TestCase* m_next = nullptr;
|
||||
TestCase* m_next = nullptr;
|
||||
test_case_func_t m_func;
|
||||
const char* m_file;
|
||||
size_t m_line;
|
||||
const char* m_name;
|
||||
const char* m_desc;
|
||||
const char* m_file;
|
||||
size_t m_line;
|
||||
const char* m_name;
|
||||
const char* m_desc;
|
||||
};
|
||||
|
||||
struct Registry {
|
||||
void add(test_case_func_t func, const char* file, size_t line, const char* name, const char* desc)
|
||||
struct Registry
|
||||
{
|
||||
void add(test_case_func_t func, const char* file, size_t line, const char* name,
|
||||
const char* desc)
|
||||
{
|
||||
TestCase* tc = new TestCase(m_last, func, file, line, name, desc);
|
||||
if (!m_first) {
|
||||
if (!m_first)
|
||||
{
|
||||
m_first = tc;
|
||||
}
|
||||
m_last = tc;
|
||||
}
|
||||
TestCase* m_first = nullptr;
|
||||
TestCase* m_last = nullptr;
|
||||
TestCase* m_last = nullptr;
|
||||
};
|
||||
|
||||
struct Env {
|
||||
std::function<void(void)> m_check_pass;
|
||||
struct Env
|
||||
{
|
||||
std::function<void(void)> m_check_pass;
|
||||
std::function<void(size_t)> m_check_fail;
|
||||
std::function<void(size_t)> m_fail;
|
||||
Registry m_registry;
|
||||
Registry m_registry;
|
||||
};
|
||||
|
||||
extern Env g_env;
|
||||
@ -98,25 +105,27 @@ template<typename IO>
|
||||
class Runner
|
||||
{
|
||||
typedef Runner<IO> Tself;
|
||||
|
||||
public:
|
||||
Runner(IO& io) : m_io(io)
|
||||
{
|
||||
g_env.m_check_pass = std::bind(&Tself::check_pass, this);
|
||||
g_env.m_check_fail = std::bind(&Tself::check_fail, this, std::placeholders::_1);
|
||||
g_env.m_fail = std::bind(&Tself::fail, this, std::placeholders::_1);
|
||||
g_env.m_fail = std::bind(&Tself::fail, this, std::placeholders::_1);
|
||||
}
|
||||
|
||||
~Runner()
|
||||
{
|
||||
g_env.m_check_pass = 0;
|
||||
g_env.m_check_fail = 0;
|
||||
g_env.m_fail = 0;
|
||||
g_env.m_fail = 0;
|
||||
}
|
||||
|
||||
void run()
|
||||
{
|
||||
do {
|
||||
} while(do_menu());
|
||||
do
|
||||
{
|
||||
} while (do_menu());
|
||||
}
|
||||
|
||||
void check_pass()
|
||||
@ -132,7 +141,8 @@ public:
|
||||
|
||||
void fail(size_t line)
|
||||
{
|
||||
protocol::output_test_end(m_io, false, m_check_pass_count + m_check_fail_count, m_check_fail_count, line);
|
||||
protocol::output_test_end(m_io, false, m_check_pass_count + m_check_fail_count,
|
||||
m_check_fail_count, line);
|
||||
bs::fatal();
|
||||
}
|
||||
|
||||
@ -141,22 +151,28 @@ protected:
|
||||
{
|
||||
protocol::output_menu_begin(m_io);
|
||||
int id = 1;
|
||||
for (TestCase* tc = g_env.m_registry.m_first; tc; tc = tc->next(), ++id) {
|
||||
for (TestCase* tc = g_env.m_registry.m_first; tc; tc = tc->next(), ++id)
|
||||
{
|
||||
protocol::output_menu_item(m_io, id, tc->name(), tc->desc());
|
||||
}
|
||||
protocol::output_menu_end(m_io);
|
||||
while(true) {
|
||||
int id;
|
||||
while (true)
|
||||
{
|
||||
int id;
|
||||
char line_buf[BS_LINE_BUF_SIZE];
|
||||
if (!protocol::input_handle(m_io, line_buf, sizeof(line_buf), id)) {
|
||||
if (!protocol::input_handle(m_io, line_buf, sizeof(line_buf), id))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (id < 0) {
|
||||
if (id < 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
TestCase* tc = g_env.m_registry.m_first;
|
||||
for (int i = 0; i != id - 1 && tc; ++i, tc = tc->next());
|
||||
if (!tc) {
|
||||
for (int i = 0; i != id - 1 && tc; ++i, tc = tc->next())
|
||||
;
|
||||
if (!tc)
|
||||
{
|
||||
bs::fatal();
|
||||
}
|
||||
m_check_pass_count = 0;
|
||||
@ -164,12 +180,13 @@ protected:
|
||||
protocol::output_test_start(m_io, tc->file(), tc->line(), tc->name(), tc->desc());
|
||||
tc->run();
|
||||
bool success = m_check_fail_count == 0;
|
||||
protocol::output_test_end(m_io, success, m_check_pass_count + m_check_fail_count, m_check_fail_count);
|
||||
protocol::output_test_end(m_io, success, m_check_pass_count + m_check_fail_count,
|
||||
m_check_fail_count);
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
IO& m_io;
|
||||
IO& m_io;
|
||||
size_t m_check_pass_count;
|
||||
size_t m_check_fail_count;
|
||||
};
|
||||
@ -177,7 +194,8 @@ protected:
|
||||
class AutoReg
|
||||
{
|
||||
public:
|
||||
AutoReg(test_case_func_t func, const char* file, size_t line, const char* name, const char* desc = nullptr)
|
||||
AutoReg(test_case_func_t func, const char* file, size_t line, const char* name,
|
||||
const char* desc = nullptr)
|
||||
{
|
||||
g_env.m_registry.add(func, file, line, name, desc);
|
||||
}
|
||||
@ -185,39 +203,59 @@ public:
|
||||
|
||||
inline void check(bool condition, size_t line)
|
||||
{
|
||||
if (!condition) {
|
||||
if (!condition)
|
||||
{
|
||||
g_env.m_check_fail(line);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
g_env.m_check_pass();
|
||||
}
|
||||
}
|
||||
|
||||
inline void require(bool condition, size_t line)
|
||||
{
|
||||
if (!condition) {
|
||||
if (!condition)
|
||||
{
|
||||
g_env.m_check_fail(line);
|
||||
g_env.m_fail(line);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
g_env.m_check_pass();
|
||||
}
|
||||
}
|
||||
|
||||
} // ::bs
|
||||
} // namespace bs
|
||||
|
||||
#define BS_NAME_LINE2( name, line ) name##line
|
||||
#define BS_NAME_LINE( name, line ) BS_NAME_LINE2( name, line )
|
||||
#define BS_UNIQUE_NAME( name ) BS_NAME_LINE( name, __LINE__ )
|
||||
#define BS_NAME_LINE2(name, line) name##line
|
||||
#define BS_NAME_LINE(name, line) BS_NAME_LINE2(name, line)
|
||||
#define BS_UNIQUE_NAME(name) BS_NAME_LINE(name, __LINE__)
|
||||
|
||||
#define TEST_CASE( ... ) \
|
||||
static void BS_UNIQUE_NAME( TEST_FUNC__ )(); \
|
||||
namespace{ bs::AutoReg BS_UNIQUE_NAME( test_autoreg__ )( &BS_UNIQUE_NAME( TEST_FUNC__ ), __FILE__, __LINE__, __VA_ARGS__ ); }\
|
||||
static void BS_UNIQUE_NAME( TEST_FUNC__ )()
|
||||
#define TEST_CASE(...) \
|
||||
static void BS_UNIQUE_NAME(TEST_FUNC__)(); \
|
||||
namespace \
|
||||
{ \
|
||||
bs::AutoReg BS_UNIQUE_NAME(test_autoreg__)(&BS_UNIQUE_NAME(TEST_FUNC__), __FILE__, \
|
||||
__LINE__, __VA_ARGS__); \
|
||||
} \
|
||||
static void BS_UNIQUE_NAME(TEST_FUNC__)()
|
||||
|
||||
#define CHECK(condition) bs::check((condition), __LINE__)
|
||||
#define REQUIRE(condition) bs::require((condition), __LINE__)
|
||||
#define FAIL() bs::g_env.m_fail(__LINE__)
|
||||
|
||||
#define BS_ENV_DECLARE() namespace bs { Env g_env; }
|
||||
#define BS_RUN(...) do { bs::IOHelper helper = bs::IOHelper(__VA_ARGS__); bs::Runner<bs::IOHelper> runner(helper); runner.run(); } while(0);
|
||||
#define BS_ENV_DECLARE() \
|
||||
namespace bs \
|
||||
{ \
|
||||
Env g_env; \
|
||||
}
|
||||
#define BS_RUN(...) \
|
||||
do \
|
||||
{ \
|
||||
bs::IOHelper helper = bs::IOHelper(__VA_ARGS__); \
|
||||
bs::Runner<bs::IOHelper> runner(helper); \
|
||||
runner.run(); \
|
||||
} while (0);
|
||||
|
||||
#endif //BSTEST_H
|
||||
#endif // BSTEST_H
|
||||
|
@ -3,21 +3,23 @@
|
||||
|
||||
BS_ENV_DECLARE();
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
while(true) {
|
||||
try{
|
||||
while (true)
|
||||
{
|
||||
try
|
||||
{
|
||||
BS_RUN();
|
||||
return 0;
|
||||
}catch(...) {
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
printf("Exception\n\n");
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("this test runs successfully", "[bluesmoke]")
|
||||
{
|
||||
CHECK(1 + 1 == 2);
|
||||
@ -38,17 +40,12 @@ TEST_CASE("another test which fails and crashes", "[bluesmoke][fail]")
|
||||
REQUIRE(false);
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("third test which should be skipped", "[.]")
|
||||
{
|
||||
FAIL();
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("this test also runs successfully", "[bluesmoke]")
|
||||
{
|
||||
|
||||
}
|
||||
TEST_CASE("this test also runs successfully", "[bluesmoke]") { }
|
||||
|
||||
TEST_CASE("environment variables can be set and read from python", "[bluesmoke]")
|
||||
{
|
||||
@ -57,4 +54,3 @@ TEST_CASE("environment variables can be set and read from python", "[bluesmoke]"
|
||||
CHECK(strcmp(res, "42") == 0);
|
||||
setenv("VAR_FROM_TEST", "24", 1);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user