#include "mm_tool.h" #include #include typedef struct { int n_ready; int n_text; char name[64]; char path[256]; } sink_t; static void on_ev(const ctl_event_t *ev, void *ud) { sink_t *s = ud; if (ev->type == CTL_EV_TEXT) s->n_text++; if (ev->type == CTL_EV_CALL_READY && ev->call) { s->n_ready++; snprintf(s->name, sizeof(s->name), "%s", ev->call->name); if (ev->call->nargs > 0 && ev->call->args[0].value) snprintf(s->path, sizeof(s->path), "%s", ev->call->args[0].value); } } static int expect(int c, const char *m) { if (!c) { fprintf(stderr, "FAIL: %s\n", m); return 0; } return 1; } int main(void) { sink_t s = {0}; mm_scan_t *mm = mm_scan_create(on_ev, &s); const char *msg = "我来读一下。\n" "\n" "invoke read_file\n" "./README.md\n" "\n" "读完了。\n"; /* byte-at-a-time */ for (size_t i = 0; msg[i]; i++) mm_scan_feed(mm, &msg[i], 1); mm_scan_finish(mm); int ok = 1; ok &= expect(s.n_ready == 1, "one ready"); ok &= expect(strcmp(s.name, "read_file") == 0, "name"); ok &= expect(strcmp(s.path, "./README.md") == 0, "path"); ok &= expect(s.n_text >= 1, "text emitted"); /* truncated: no execute */ sink_t s2 = {0}; mm_scan_t *mm2 = mm_scan_create(on_ev, &s2); const char *trunc = "\ninvoke read_file\n"; mm_scan_feed(mm2, trunc, strlen(trunc)); mm_scan_finish(mm2); ok &= expect(s2.n_ready == 0, "trunc no ready"); mm_scan_destroy(mm); mm_scan_destroy(mm2); if (!ok) return 1; printf("test_mm_tool: OK\n"); return 0; }