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:
M | main.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);
}
}