gawk

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

commit f93bc3de44e7de77994865b862783316b4736f75
parent 87e78340cd1dde90cef00cb1bed8a0f475fbb6eb
Author: Jacob R. Edwards <jacobouno@protonmail.com>
Date:   Sat, 19 Dec 2020 19:22:57 -0800

Improve command parsing and move alot of code to functions

The bigger commands are now in their own functions prefixed by `c'.

The command is now only ever the first character read allowing no
separators between the command and it's first argument.

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

diff --git a/main.c b/main.c @@ -35,6 +35,8 @@ #define ARGV_MAX 16 #define ARG_SEP ":\t " +int gawk(int depth, const char *tmpdir, const char *host, const char *path, const char *port); + int exists(const char *path) { @@ -277,19 +279,56 @@ gawkat(const char *path) return 0; } -/* returns `<0` on error, if positive `n - 1` is - * be returned to the caller. */ +int +cgoto(int argc, char **argv, int depth, const char *tmpdir, const char *host, const char *path, const char *port) +{ + char npath[PATH_MAX]; + const char *nhost, *nport; + + nhost = host; + nport = port; + + if (argc == 0) + strcpy(npath, "/"); + else if (argc == 1) + newpath(npath, argv[0]); + else { + newpath(npath, argv[1]); + nhost = argv[1]; + if (argc == 2) + nport = argv[2]; + } + + return gawk(depth, tmpdir, nhost, npath, nport); +} + +int +cback(int argc, char **argv) +{ + int back; + + if (argc == 0) + return 1; + + back = strtoui(argv[0]); + if (back < 0) { + warn("invalid number '%s'", argv[0]); + return 0; + } + + return back; +} + int gawk(int depth, const char *tmpdir, const char *host, const char *path, const char *port) { char *argv[ARGV_MAX]; - char inbuf[PATH_MAX + HOST_NAME_MAX + PROTO_MAX]; - char prompt[64]; /* you wouldn't want it longer anyway */ char cache[PATH_MAX]; - const char *nreq[3]; + char inbuf[PATH_MAX + HOST_NAME_MAX + PROTO_MAX]; + char prompt[64]; int argc; - int unlinkit; int done; + int unlinkit; ++depth; @@ -306,58 +345,38 @@ gawk(int depth, const char *tmpdir, const char *host, const char *path, const ch snprintf(prompt, sizeof(prompt), "[%s] %s ", host, path); gawkat(cache); while (!done && input(inbuf, sizeof(inbuf), prompt, stdin) == 0) { - argc = argsplit(argv, LEN(argv), inbuf, ARG_SEP); - if (argc <= 0) { - if (argc < 0) - warn("Too many arguments"); + if (*inbuf == '\0') + continue; + argc = argsplit(argv, LEN(argv), inbuf + 1, ARG_SEP); + if (argc < 0) { +too_many_args: + warnx("Too many arguments"); continue; } - if (strlen(*argv) > 1) - goto invalid_input; - switch (**argv) { - case 'q': /* quit */ - if (argc > 1) - goto invalid_input; + switch (*inbuf) { + case 'q': + if (argc != 0) + goto too_many_args; done = depth; break; - case 'p': /* print */ + case 'p': gawkat(cache); break; - case 'b': /* back */ - if (argc > 2) - goto invalid_input; - if (argc == 1) - done = 1; - else if (argc == 2) - done = strtoui(argv[1]); + case 'b': + if (argc > 1) + goto too_many_args; + done = cback(argc, argv); break; - case 'g': /* goto or gawk */ + case 'g': if (argc > 4) - goto invalid_input; - - nreq[0] = host; - nreq[1] = path; - nreq[2] = port; - - /* NOTE: relative path's not implemented */ - if (argc == 1) - nreq[1] = "/"; - else if (argc == 2) - nreq[1]= argv[1]; - else { - nreq[0] = argv[1]; - nreq[1] = argv[2]; - if (argc == 3) - nreq[2] = argv[3]; - } - done = gawk(depth, tmpdir, nreq[0], nreq[1], nreq[2]); + goto too_many_args; + done = cgoto(argc, argv, depth, tmpdir, host, path, port); if (done == 0) gawkat(cache); break; default: -invalid_input: - warnc(EINVAL, "invalid command or arguments for '%s'", argv[0]); + warnx("invalid command '%c'", *inbuf); } }