#include "ctl.h" #include #include #include /* Heredoc args: `arg <type == CTL_EV_TEXT && c->text_len + ev->text_len < sizeof(c->text)) { memcpy(c->text + c->text_len, ev->text, ev->text_len); c->text_len += ev->text_len; } if (ev->type != CTL_EV_CALL_READY) return; c->ready++; c->nargs = ev->call->nargs; for (int i = 0; i < ev->call->nargs; i++) { snprintf(c->keys[i], sizeof(c->keys[i]), "%s", ev->call->args[i].key); free(c->vals[i]); c->vals[i] = malloc(ev->call->args[i].value_len + 1); memcpy(c->vals[i], ev->call->args[i].value, ev->call->args[i].value_len); c->vals[i][ev->call->args[i].value_len] = 0; c->lens[i] = ev->call->args[i].value_len; } } static void cap_free(cap_t *c) { for (int i = 0; i < CTL_MAX_ARGS; i++) free(c->vals[i]); memset(c, 0, sizeof(*c)); } /* feed in `chunk`-byte pieces; finish if asked */ static ctl_status_t run(const char *s, size_t n, size_t chunk, int finish, cap_t *c, ctl_parser_stats_t *st) { memset(c, 0, sizeof(*c)); ctl_parser_t *p = ctl_parser_create(on_ev, c); ctl_status_t rc = CTL_OK; for (size_t i = 0; i < n && rc == CTL_OK; i += chunk) { size_t k = n - i < chunk ? n - i : chunk; rc = ctl_parser_feed(p, s + i, k); } if (rc == CTL_OK && finish) rc = ctl_parser_finish(p); if (st) ctl_parser_stats(p, st); ctl_parser_destroy(p); return rc; } static const char *BODY = "all:\n" "\tgcc -o app main.c\n" "\n" "end\n" "call x y\n" "arg path 3\n" "```\n" " EOF\n" "last line\n"; static const char *STREAM = "Writing the Makefile.\n" "call w1 write_file\n" "arg path Makefile\n" "arg content <