gawk

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

commit 709e957b51b9d7d1e4716b52adc5d2cadb49b5ca
parent 06851ef57ec48bea6d8f8a3c7e1a9afc8b9b482d
Author: Jacob R. Edwards <jacobouno@protonmail.com>
Date:   Tue,  5 Jan 2021 23:54:58 -0800

Use a struct for command function pointer and arguments

This makes the program much easier to follow and change, the old
commands struct is now the bind struct.

Diffstat:
Mconfig.def.h | 4++--
Mgawk.h | 6++++++
Mmain.c | 80+++++++++++++++++++++++++++++++++++--------------------------------------------
3 files changed, 43 insertions(+), 47 deletions(-)

diff --git a/config.def.h b/config.def.h @@ -17,7 +17,7 @@ static char const *const separators[] = { ";\n", "|", " \t," }; -static const struct command item_commands[] = { +static const struct bind itembinds[] = { /* name, function */ { 'e', cextern }, { 'f', cfetch }, @@ -30,7 +30,7 @@ static const struct command item_commands[] = { { 'v', cprintv } }; -static const struct command commands[] = { +static const struct bind binds[] = { /* name, function */ { 'u', sunwind }, { 'G', sgoto }, diff --git a/gawk.h b/gawk.h @@ -25,6 +25,12 @@ enum pstatus { NEXT = -2, FAIL, PASS }; /* pipe status */ typedef int (command)(int, char const **, int, char const **); struct command { + char const *argv[MY_ARGV_MAX]; + command *f; + int argc; +}; + +struct bind { int c; command *f; }; diff --git a/main.c b/main.c @@ -262,27 +262,27 @@ gphsplit(char const **item, int size, char *buf) } command * -get_command(char const *s, struct command const *commands, int size) +getcom(char const *s, struct bind const *binds, int size) { int i; if (strlen(s) != 1) return NULL; for (i = 0; i < size; ++i) - if (*s == commands[i].c) - return commands[i].f; + if (*s == binds[i].c) + return binds[i].f; return NULL; } int -runpipe(int count, command **commands, int *indexes, int *acs, - char const *avs[MY_PIPE_MAX][MY_ARGV_MAX], char const **item) +runpipe(struct command *cmds, int *indexes, int count, char const **item) { int i; int r; for (i = 0; i < count; ++i) { - r = commands[i](acs[i], avs[i], indexes[i]++, item); + r = cmds[i].f(cmds[i].argc, cmds[i].argv, + indexes[i]++, item); if (r != PASS) return r; } @@ -290,8 +290,7 @@ runpipe(int count, command **commands, int *indexes, int *acs, } int -pipeitems(char const *cache, int count, command **const commands, - int *acs, char const *avs[MY_PIPE_MAX][MY_ARGV_MAX]) +runpipes(char const *cache, struct command *cmds, int count) { FILE *fp; char buf[MY_LINE_MAX]; @@ -308,64 +307,55 @@ pipeitems(char const *cache, int count, command **const commands, error = 0; while (error != FAIL && fgets(buf, sizeof(buf), fp) && *buf != '.') if (gphsplit(item, sizeof(item), buf) == 0) - error = runpipe(count, commands, indexes, acs, avs, item); + error = runpipe(cmds, indexes, count, item); wfclose(fp); return error; } int -run_command(int argc, char const **argv, int depth, char const **addr) -{ - command *c; - - c = get_command(*argv, commands, LEN(commands)); - if (c == NULL) { - warn(0, "'%s': Not a command.", *argv); - return ERROR; - } - return c(argc, argv, depth, addr); -} - -int execute(char const *cache, char *input, int depth, char const **addr) { - char const *avs[MY_PIPE_MAX][MY_ARGV_MAX]; - char *cbufs[MY_PIPE_MAX]; - command *commands[MY_PIPE_MAX]; - int acs[MY_PIPE_MAX]; - int cbufslen; + char *bufs[MY_PIPE_MAX]; int i; + int nbufs; + struct command cmds[MY_PIPE_MAX]; if (*input == '\0') return ERROR; - cbufslen = argsplit(cbufs, LEN(cbufs), input, separators[1], 0); - for (i = 0; i < cbufslen; ++i) { - if (i >= LEN(avs)) { - warn(0, "Pipeline too long."); - return ERROR; - } - acs[i] = argsplit(avs[i], LEN(avs[i]), cbufs[i], separators[2], 1); - if (acs[i] < 1) { - if (acs[i] == 0) + nbufs = argsplit(bufs, LEN(bufs), input, separators[1], 0); + if (nbufs < 0) { + warn(0, "Pipeline too long."); + return ERROR; + } + + for (i = 0; i < nbufs; ++i) { + cmds[i].argc = argsplit(cmds[i].argv, LEN(cmds[i].argv), + bufs[i], separators[2], 1); + if (cmds[i].argc < 1) { + if (cmds[i].argc == 0) warn(0, "Empty pipe (#%d)", ++i); - else warn(E2BIG, "'%s'", avs[i][0]); + else warn(E2BIG, "'%s'", cmds[i].argv[0]); return ERROR; } } - for (i = 0; i < cbufslen; ++i) { - commands[i] = get_command(avs[i][0], - item_commands, LEN(item_commands)); - if (commands[i] == NULL) { - if (i == 0) - return run_command(acs[0], avs[0], depth, addr); - warn(0, "'%s': Not a command.", avs[i][0]); + for (i = 0; i < nbufs; ++i) { + cmds[i].f = getcom(cmds[i].argv[0], itembinds, LEN(itembinds)); + if (cmds[i].f == NULL) { + if (i == 0) { + cmds[i].f = getcom(cmds[i].argv[0], binds, + LEN(binds)); + if (cmds[i].f != NULL) + return cmds[i].f(cmds[i].argc, + cmds[i].argv, depth, addr); + } + warn(0, "'%s': Not a command.", cmds[i].argv[0]); return ERROR; } } - return pipeitems(cache, cbufslen, commands, acs, avs); + return runpipes(cache, cmds, nbufs); } void