gawk

[old] Sed-like interface to the Gopher protocol
Log | Files | Refs | LICENSE

commit c9a452e99bc16bf8b4086425c6534f7a17f6484e
parent 2590cb93cc652a98c49f57a4efb72770dd192228
Author: Jacob R. Edwards <jacobouno@protonmail.com>
Date:   Sun, 20 Dec 2020 13:52:25 -0800

Allow multiple statements on one line

Statements can now be separated by `;` aswell as `\n`. Also, commands
can have whitespace before them.

Diffstat:
Mmain.c | 64++++++++++++++++++++++++++++++++++++++++++----------------------
1 file changed, 42 insertions(+), 22 deletions(-)

diff --git a/main.c b/main.c @@ -117,18 +117,35 @@ connect_to(const char *host, const char *proto) int input(char *buf, int size, const char *prompt, FILE *fp) { - int len; + int next; + static int len; + static char bb[ARG_MAX]; + + if (len <= 0) { + fputs(prompt, stderr); +refill_bufbuf: + if (fgets(bb + len, sizeof(bb) - len, fp) == NULL) + return 1; + len = strlen(bb); + } - fputs(prompt, stderr); - if (fgets(buf, size, fp) == NULL) - return 1; + next = strcspn(bb, ";\n"); + if (bb[next] == '\0') { + if (len >= sizeof(buf) - 1) { +too_big: + warnc(E2BIG, NULL); + return 1; + } + goto refill_bufbuf; + } + if (next >= size) + goto too_big; + + bb[next++] = '\0'; + strlcpy(buf, bb, size); + memmove(bb, bb + next, len - next); + len -= next; - len = strlen(buf); - if (len >= size && buf[size - 1] != '\n') - warnx("maximum of %d bytes: Input too large.", size); - else if (len > 0) - buf[len - 1] = '\0'; - return 0; } @@ -367,10 +384,8 @@ cback(int argc, const char **argv) int execute(int command, int argc, const char **argv, int depth, const char *cache, - const char *host, const char *path, const char *port) + const char *tmpdir, const char *host, const char *path, const char *port) { - int done; - switch (command) { case 'q': if (argc != 0) @@ -389,10 +404,7 @@ execute(int command, int argc, const char **argv, int depth, const char *cache, case 'g': if (argc > 4) goto too_many_args; - done = cgoto(argc, argv, depth, cache, host, path, port); - if (done == 0) - gawkat(cache); - return done; + return cgoto(argc, argv, depth, tmpdir, host, path, port); break; default: warnx("invalid command '%c'", command); @@ -412,6 +424,7 @@ gawk(int depth, const char *tmpdir, const char *host, const char *path, const ch char prompt[64]; int argc; int done; + char *start; int unlinkit; ++depth; @@ -427,14 +440,21 @@ gawk(int depth, const char *tmpdir, const char *host, const char *path, const ch done = 0; snprintf(prompt, sizeof(prompt), "[%s] %s ", host, path); - gawkat(cache); while (!done && input(inbuf, sizeof(inbuf), prompt, stdin) == 0) { - if (*inbuf != '\0') { - argc = argsplit(argv, LEN(argv), inbuf + 1, ARG_SEP); + start = inbuf + strspn(inbuf, " \t"); + if (*start != '\0') { + argc = argsplit(argv, LEN(argv), start + 1, ARG_SEP); if (argc < 0) { - warnc(E2BIG, "'%c'", *inbuf); + warnc(E2BIG, "'%c'", *start); } else { - done = execute(*inbuf, argc, (const char **)argv, depth, cache, host, path, port); + /* NOTE: I'v been avoiding it but + * I think a struct would be more + * than appropriate. + */ + done = execute(*start, argc, + (const char **)argv, + depth, cache, tmpdir, + host, path, port); } } }