#include "t.h" #include #ifndef TOBI_BIN #define TOBI_BIN "./tobi" #endif #ifndef TOBI_SRC_DIR #define TOBI_SRC_DIR "." #endif static int write_blob(const char *path, const unsigned char *data, size_t len) { FILE *fp = fopen(path, "wb"); if (!fp) { return 0; } int ok = fwrite(data, 1, len, fp) == len; return fclose(fp) == 0 && ok; } static char *run_capture(const char *args, int *status) { char cmd[1024]; snprintf(cmd, sizeof(cmd), "%s %s 2>/dev/null", TOBI_BIN, args); FILE *fp = popen(cmd, "r"); if (!fp) { *status = 99; return NULL; } size_t cap = 4096; size_t len = 0; char *buf = malloc(cap); if (!buf) { (void)pclose(fp); *status = 99; return NULL; } int c = 0; while ((c = fgetc(fp)) != EOF) { if (len + 1 == cap) { cap *= 2; char *nb = realloc(buf, cap); if (!nb) { free(buf); (void)pclose(fp); *status = 99; return NULL; } buf = nb; } buf[len++] = (char)c; } buf[len] = '\0'; int rc = pclose(fp); *status = WIFEXITED(rc) ? WEXITSTATUS(rc) : 99; return buf; } int t_cli(void) { int st = 0; char path[512]; snprintf(path, sizeof(path), "%s/sam/m0.aml", TOBI_SRC_DIR); char args[700]; snprintf(args, sizeof(args), "%s", path); char *s = run_capture(args, &st); T_CHECK(st == 0); T_STR(s, "method MTH0"); T_STR(s, "return Local0"); free(s); snprintf(args, sizeof(args), "--dis %s", path); s = run_capture(args, &st); T_CHECK(st == 0); T_STR(s, "0x0000"); T_STR(s, "MethodOp"); free(s); snprintf(args, sizeof(args), "--json %s", path); s = run_capture(args, &st); T_CHECK(st == 0); T_STR(s, "\"ir\""); T_STR(s, "\"kind\":\"method\""); free(s); snprintf(args, sizeof(args), "--dot %s", path); s = run_capture(args, &st); T_CHECK(st == 0); T_STR(s, "digraph tobi_cfg"); T_STR(s, "method"); free(s); snprintf(args, sizeof(args), "--raw %s", path); s = run_capture(args, &st); T_CHECK(st == 0); T_STR(s, "checksum_sum=0x00"); T_STR(s, "checksum_valid=false"); free(s); { unsigned char use_file[] = {0x14,0x0d,'U','S','E','0',0x00,0xa4,'C','A','L','0',0x0a,0x05}; unsigned char cal_file[] = {0x14,0x08,'C','A','L','0',0x01,0xa4,0x68}; const char *use_path = "/tmp/tobi_cli_use.aml"; const char *cal_path = "/tmp/tobi_cli_cal.aml"; T_CHECK(write_blob(use_path, use_file, sizeof(use_file))); T_CHECK(write_blob(cal_path, cal_file, sizeof(cal_file))); snprintf(args, sizeof(args), "%s %s", use_path, cal_path); s = run_capture(args, &st); T_CHECK(st == 0); T_STR(s, "method USE0"); T_STR(s, "CAL0(0x5)"); free(s); } s = run_capture("--help", &st); T_CHECK(st == 0); T_STR(s, "usage: tobi"); free(s); s = run_capture("--version", &st); T_CHECK(st == 0); T_STR(s, "tobi"); free(s); snprintf(path, sizeof(path), "%s/sam/m0.aml", TOBI_SRC_DIR); snprintf(args, sizeof(args), "--json --dis %s", path); s = run_capture(args, &st); T_CHECK(st == 2); free(s); s = run_capture("--definitely-not-real", &st); T_CHECK(st == 2); free(s); snprintf(path, sizeof(path), "%s/sam/bad0.aml", TOBI_SRC_DIR); snprintf(args, sizeof(args), "--strict %s", path); s = run_capture(args, &st); T_CHECK(st != 0); free(s); return 0; }