8 #define LINEFMT "%s, line %" PFMT64u ": "
18 #define DO_KEY_STR(key, field) free(test->field.value);
25 char *
end = strchr(
buf,
'\n');
36 *linesz = strlen(
buf);
57 eprintf(
"Error: Invalid string syntax, use <<EOF instead of '...'\n");
61 if (
val[0] ==
'<' &&
val[1] ==
'<') {
63 const char *endtoken =
val + 2;
65 eprintf(
"Error: Missing opening end token after <<\n");
68 if (strcmp(endtoken,
"EOF") != 0) {
71 eprintf(
"Error: End token must be \"EOF\", got \"%s\" instead.", endtoken);
75 char *
line = *nextline;
80 char *
end = strstr(
line, endtoken);
96 }
while ((
line = *nextline));
97 eprintf(
"Error: Missing closing end token %s\n", endtoken);
125 char *
line = contents;
142 }
else if (!
val && !(strcmp(
line,
"RUN") == 0)) {
143 eprintf(
"Error: No value for key \"%s\".\n",
line);
148 if (strcmp(
line,
"RUN") == 0) {
149 test->run_line = linenum;
150 if (!
test->cmds.value) {
154 if (!(
test->expect.value ||
test->expect_err.value)) {
156 " (did you forget an EOF?)\n",
168 #define DO_KEY_STR(key, field) \
169 if (strcmp(line, key) == 0) { \
170 if (test->field.value) { \
171 free(test->field.value); \
172 eprintf(LINEFMT "Warning: Duplicate key \"%s\"\n", file, linenum, key); \
174 test->field.line_begin = linenum; \
175 test->field.value = read_string_val(&nextline, val, &linenum); \
176 test->field.line_end = linenum + 1; \
177 if (!test->field.value) { \
178 eprintf(LINEFMT "Error: Failed to read value for key \"%s\"\n", file, linenum, key); \
184 #define DO_KEY_BOOL(key, field) \
185 if (strcmp(line, key) == 0) { \
186 if (test->field.value) { \
187 eprintf(LINEFMT "Warning: Duplicate key \"%s\"\n", file, linenum, key); \
189 test->field.set = true; \
191 char *cmt = strchr(val, '#'); \
195 while (cmt > val && *cmt == ' ') { \
200 if (!strcmp(val, "1")) { \
201 test->field.value = true; \
202 } else if (!strcmp(val, "0")) { \
203 test->field.value = false; \
205 eprintf(LINEFMT "Error: Invalid value \"%s\" for boolean key \"%s\", only \"1\" or \"0\" allowed.\n", file, linenum, val, key); \
211 #define DO_KEY_NUM(key, field) \
212 if (strcmp(line, key) == 0) { \
213 if (test->field.value) { \
214 eprintf(LINEFMT "Warning: Duplicate key \"%s\"\n", file, linenum, key); \
216 test->field.set = true; \
218 char *cmt = strchr(val, '#'); \
222 while (cmt > val && *cmt == ' ') { \
228 test->field.value = strtol(val, &endval, 0); \
229 if (!endval || *endval) { \
230 eprintf(LINEFMT "Error: Invalid value \"%s\" for numeric key \"%s\", only numbers allowed.\n", file, linenum, val, key); \
242 }
while ((
line = nextline));
247 eprintf(
"Warning: found test tokens at the end of \"%s\" without RUN.\n",
file);
275 if (!file_tokens || rz_list_empty(file_tokens)) {
290 char *second = strchr(
arch,
'_');
294 char *third = strchr(second,
'_');
299 *bitsout = atoi(third);
302 *bitsout = atoi(second);
318 eprintf(
"Failed to parse arch/cpu/bits from path %s\n",
file);
334 char *
line = contents;
370 eprintf(
LINEFMT "Warning: Mode specifies neither assemble nor disassemble.\n",
file, linenum);
375 char *disasm = strchr(
line,
'"');
381 char *
hex = strchr(disasm,
'"');
391 while (*
hex && *
hex ==
' ') {
396 char *latecmt = strchr(
hex,
'#');
416 size_t hexlen = strlen(
hex);
442 test->line = linenum;
449 if (endptr && *endptr) {
459 }
while ((
line = nextline));
496 char *
line = contents;
509 char *broken_token = strstr(
line,
"BROKEN");
511 *broken_token =
'\0';
524 test->line = linenum;
530 test->broken = broken_token ?
true :
false;
532 }
while ((
line = nextline));
550 switch (
test->type) {
593 if (!rz_list_empty(tokens)) {
598 *load_plugins =
false;
599 rz_list_foreach (tokens, it, token) {
600 if (!strcmp(token,
"asm")) {
604 if (!strcmp(token,
"json")) {
608 if (!strcmp(token,
"extras")) {
609 *load_plugins =
true;
623 const char *neg_subname = subname + strlen(
"not-");
624 const char *second_dash = strchr(neg_subname,
'-');
626 if (strncmp(neg_subname,
RZ_TEST_ARCH_OS, second_dash - neg_subname) &&
632 if (!strncmp(subname,
RZ_TEST_ARCH_OS, strlen(subname) - strlen(
"-any"))) {
642 eprintf(
"Directories for loading tests too deep: %s\n",
path);
655 rz_list_foreach (dir, it, subname) {
656 if (*subname ==
'.') {
659 if (!strcmp(subname,
"extras")) {
661 eprintf(
"Skipping %s" RZ_SYS_DIR "%s because it requires additional dependencies.\n",
path, subname);
665 eprintf(
"Skipping %s" RZ_SYS_DIR "%s because it does not match the current platform.\n",
path, subname);
686 bool load_plugins =
false;
701 test->path = pooled_path;
702 test->cmd_test = *it;
703 test->cmd_test->load_plugins = load_plugins;
721 test->path = pooled_path;
722 test->asm_test = *it;
740 test->path = pooled_path;
741 test->json_test = *it;
742 test->json_test->load_plugins = load_plugins;
766 if (!fuzz_test->
file) {
777 test->fuzz_test = fuzz_test;
793 rz_list_foreach (dir, it, subname) {
794 if (*subname ==
'.') {
int bits(struct state *s, int need)
static static fork const void static count static fd const char const char static newpath const char static path const char path
RZ_API void Ht_() free(HtName_(Ht) *ht)
RZ_API RZ_OWN void * rz_list_pop(RZ_NONNULL RzList *list)
Removes and returns the last element of the list.
RZ_API RZ_BORROW void * rz_list_last(RZ_NONNULL const RzList *list)
Returns the last element of the list.
RZ_API void rz_list_free(RZ_NONNULL RzList *list)
Empties the list and frees the list pointer.
void * malloc(size_t size)
return strdup("=SP r13\n" "=LR r14\n" "=PC r15\n" "=A0 r0\n" "=A1 r1\n" "=A2 r2\n" "=A3 r3\n" "=ZF zf\n" "=SF nf\n" "=OF vf\n" "=CF cf\n" "=SN or0\n" "gpr lr .32 56 0\n" "gpr pc .32 60 0\n" "gpr cpsr .32 64 0 ____tfiae_________________qvczn\n" "gpr or0 .32 68 0\n" "gpr tf .1 64.5 0 thumb\n" "gpr ef .1 64.9 0 endian\n" "gpr jf .1 64.24 0 java\n" "gpr qf .1 64.27 0 sticky_overflow\n" "gpr vf .1 64.28 0 overflow\n" "gpr cf .1 64.29 0 carry\n" "gpr zf .1 64.30 0 zero\n" "gpr nf .1 64.31 0 negative\n" "gpr itc .4 64.10 0 if_then_count\n" "gpr gef .4 64.16 0 great_or_equal\n" "gpr r0 .32 0 0\n" "gpr r1 .32 4 0\n" "gpr r2 .32 8 0\n" "gpr r3 .32 12 0\n" "gpr r4 .32 16 0\n" "gpr r5 .32 20 0\n" "gpr r6 .32 24 0\n" "gpr r7 .32 28 0\n" "gpr r8 .32 32 0\n" "gpr r9 .32 36 0\n" "gpr r10 .32 40 0\n" "gpr r11 .32 44 0\n" "gpr r12 .32 48 0\n" "gpr r13 .32 52 0\n" "gpr r14 .32 56 0\n" "gpr r15 .32 60 0\n" "gpr r16 .32 64 0\n" "gpr r17 .32 68 0\n")
static bool database_load(RzTestDatabase *db, const char *path, int depth)
static char * readline(char *buf, size_t *linesz)
static char * read_string_val(char **nextline, const char *val, ut64 *linenum)
RZ_API RzJsonTest * rz_test_json_test_new(void)
static void database_load_fuzz_file(RzTestDatabase *db, const char *path, const char *file)
static RzTestType test_type_for_path(const char *path, bool *load_plugins)
RZ_API RzPVector * rz_test_load_cmd_test_file(const char *file)
RZ_API bool rz_test_test_database_load(RzTestDatabase *db, const char *path)
RZ_API RzTestDatabase * rz_test_test_database_new(void)
static bool skip_archos(const char *subname)
RZ_API void rz_test_test_database_free(RzTestDatabase *db)
RZ_API RzCmdTest * rz_test_cmd_test_new(void)
#define DO_KEY_NUM(key, field)
RZ_API RzPVector * rz_test_load_json_test_file(const char *file)
RZ_API void rz_test_fuzz_test_free(RzFuzzTest *test)
RZ_API void rz_test_test_free(RzTest *test)
RZ_API bool rz_test_test_database_load_fuzz(RzTestDatabase *db, const char *path)
RZ_API RzAsmTest * rz_test_asm_test_new(void)
RZ_API void rz_test_json_test_free(RzJsonTest *test)
RZ_API void rz_test_cmd_test_free(RzCmdTest *test)
RZ_API RzPVector * rz_test_load_asm_test_file(RzStrConstPool *strpool, const char *file)
static bool parse_asm_path(const char *path, RzStrConstPool *strpool, const char **arch_out, const char **cpuout, int *bitsout)
#define DO_KEY_STR(key, field)
#define DO_KEY_BOOL(key, field)
RZ_API void rz_test_asm_test_free(RzAsmTest *test)
static const char hex[16]
#define rz_return_val_if_fail(expr, val)
RZ_API bool rz_file_is_directory(const char *str)
RZ_API bool rz_file_exists(const char *str)
RZ_API RZ_OWN char * rz_file_slurp(const char *str, RZ_NULLABLE size_t *usz)
RZ_API int rz_hex_str2bin(const char *in, ut8 *out)
Convert an input string in into the binary form in out.
RZ_API RzList * rz_str_split_duplist(const char *str, const char *c, bool trim)
Split the string str according to the substring c and returns a RzList with the result.
RZ_API void rz_str_trim(RZ_NONNULL RZ_INOUT char *str)
Removes whitespace characters (space, tab, newline etc.) from the beginning and end of a string.
RZ_API bool rz_str_startswith(RZ_NONNULL const char *str, RZ_NONNULL const char *needle)
Checks if a string starts with a specifc sequence of characters (case sensitive)
RZ_API RzList * rz_str_split_list(char *str, const char *c, int n)
Split the string str according to the substring c and returns a RzList with the result.
RZ_API bool rz_str_endswith(RZ_NONNULL const char *str, RZ_NONNULL const char *needle)
Checks if a string ends with a specifc sequence of characters (case sensitive)
RZ_API const char * rz_str_constpool_get(RzStrConstPool *pool, const char *str)
RZ_API void rz_str_constpool_fini(RzStrConstPool *pool)
RZ_API bool rz_str_constpool_init(RzStrConstPool *pool)
RZ_API RZ_OWN char * rz_strbuf_drain(RzStrBuf *sb)
RZ_API char * rz_strbuf_get(RzStrBuf *sb)
RZ_API bool rz_strbuf_append(RzStrBuf *sb, const char *s)
RZ_API const char * rz_strbuf_setf(RzStrBuf *sb, const char *fmt,...) RZ_PRINTF_CHECK(2
RZ_API void rz_strbuf_fini(RzStrBuf *sb)
RZ_API RzStrBuf * rz_strbuf_new(const char *s)
RZ_API void rz_strbuf_free(RzStrBuf *sb)
RZ_API void rz_strbuf_init(RzStrBuf *sb)
RZ_API RzList * rz_sys_dir(const char *path)
enum rz_test_test_type_t RzTestType
#define RZ_CMD_TEST_FOREACH_RECORD_NOP(name, field)
#define RZ_CMD_TEST_FOREACH_RECORD(macro_str, macro_bool, macro_int)
@ RZ_ASM_TEST_MODE_BIG_ENDIAN
@ RZ_ASM_TEST_MODE_BROKEN
@ RZ_ASM_TEST_MODE_ASSEMBLE
@ RZ_ASM_TEST_MODE_DISASSEMBLE
RZ_API void rz_pvector_init(RzPVector *vec, RzPVectorFree free)
RZ_API RzPVector * rz_pvector_new(RzPVectorFree free)
void(* RzPVectorFree)(void *e)
static void ** rz_pvector_push(RzPVector *vec, void *x)
RZ_API void rz_pvector_free(RzPVector *vec)
RZ_API void rz_pvector_clear(RzPVector *vec)
#define rz_pvector_foreach(vec, it)
ut64(WINAPI *w32_GetEnabledXStateFeatures)()