Development discussion for mrsh.

You can setup your Git repository like so:

git config sendemail.to ~emersion/mrsh-dev@lists.sr.ht
1 2

[PATCH] Abort when unspecified commands are attempted

Details
Message ID
<20181227195939.28194-1-sir@cmpwn.com>
Sender timestamp
1545940779
DKIM signature
permerror
Download raw message
Patch: +42 -0
---
 builtin/builtin.c     | 28 ++++++++++++++++++++++++++++
 builtin/unspecified.c | 11 +++++++++++
 include/builtin.h     |  2 ++
 meson.build           |  1 +
 4 files changed, 42 insertions(+)
 create mode 100644 builtin/unspecified.c

diff --git a/builtin/builtin.c b/builtin/builtin.c
index 1ef2258..2692532 100644
--- a/builtin/builtin.c
@@ -36,12 +36,40 @@ static const struct builtin builtins[] = {
 	{ "unset", builtin_unset, true },
 };
 
+// The following commands are explicitly unspecified by POSIX
+static const char *unspecified_names[] = {
+	"alloc", "autoload", "bind", "bindkey", "builtin", "bye", "caller", "cap",
+	"chdir", "clone", "comparguments", "compcall", "compctl", "compdescribe",
+	"compfiles", "compgen", "compgroups", "complete", "compquote", "comptags",
+	"comptry", "compvalues", "declare", "dirs", "disable", "disown", "dosh",
+	"echotc", "echoti", "help", "history", "hist", "let", "local", "login",
+	"logout", "map", "mapfile", "popd", "print", "pushd", "readarray", "repeat",
+	"savehistory", "source", "shopt", "stop", "suspend", "typeset", "whence"
+};
+
+static const struct builtin unspecified = {
+	.name = "unspecified",
+	.func = builtin_unspecified,
+	.special = false,
+};
+
 static int builtin_compare(const void *_a, const void *_b) {
 	const struct builtin *a = _a, *b = _b;
 	return strcmp(a->name, b->name);
 }
 
+static int unspecified_compare(const void *_a, const void *_b) {
+	const char *a = _a;
+	const char * const *b = _b;
+	return strcmp(a, *b);
+}
+
 static const struct builtin *get_builtin(const char *name) {
+	if (bsearch(name, unspecified_names,
+			sizeof(unspecified_names) / sizeof(unspecified_names[0]),
+			sizeof(unspecified_names[0]), unspecified_compare)) {
+		return &unspecified;
+	}
 	struct builtin key = { .name = name };
 	return bsearch(&key, builtins, sizeof(builtins) / sizeof(builtins[0]),
 		sizeof(builtins[0]), builtin_compare);
diff --git a/builtin/unspecified.c b/builtin/unspecified.c
new file mode 100644
index 0000000..43a2aed
--- /dev/null
@@ -0,0 +1,11 @@
+#include <mrsh/shell.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include "builtin.h"
+
+int builtin_unspecified(struct mrsh_state *state, int argc, char *argv[]) {
+	// Ref: http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_09_01_01
+	fprintf(stderr, "%s: The behavior of this command is undefined. "
+			"This is an error in your script. Aborting.\n", argv[0]);
+	exit(1);
+}
diff --git a/include/builtin.h b/include/builtin.h
index 61eeae0..ed437b2 100644
--- a/include/builtin.h
+++ b/include/builtin.h
@@ -28,6 +28,8 @@ int builtin_umask(struct mrsh_state *state, int argc, char *argv[]);
 int builtin_unalias(struct mrsh_state *state, int argc, char *argv[]);
 int builtin_unset(struct mrsh_state *state, int argc, char *argv[]);
 
+int builtin_unspecified(struct mrsh_state *state, int argc, char *argv[]);
+
 const char *print_options(struct mrsh_state *state);
 
 #endif
diff --git a/meson.build b/meson.build
index 8e1a7b8..2ee8c60 100644
--- a/meson.build
+++ b/meson.build
@@ -67,6 +67,7 @@ lib_mrsh = library(
 		'builtin/umask.c',
 		'builtin/unalias.c',
 		'builtin/unset.c',
+		'builtin/unspecified.c',
 		'getopt.c',
 		'hashtable.c',
 		'parser/arithm.c',
-- 
2.20.1
Details
Message ID
<UOFkAnd7C1QBjnXy1kWZoNRXkxVBFKW8Ms39lyUvmaLmqO-8pCteFhWjDRvX8nYWd990pNTWssGw-sh2WftcxZWjA4ILXLLRh8VV2qET7Fw=@emersion.fr>
In-Reply-To
<20181227195939.28194-1-sir@cmpwn.com> (view parent)
Sender timestamp
1546019188
DKIM signature
pass
Download raw message
Pushed:

To git.sr.ht:~emersion/mrsh
   a217d07..4296e38  master -> master

Thanks!