aboutsummaryrefslogtreecommitdiff
path: root/sys/cmd/rc/code.dep
diff options
context:
space:
mode:
Diffstat (limited to 'sys/cmd/rc/code.dep')
-rw-r--r--sys/cmd/rc/code.dep166
1 files changed, 166 insertions, 0 deletions
diff --git a/sys/cmd/rc/code.dep b/sys/cmd/rc/code.dep
new file mode 100644
index 0000000..7fdd4bc
--- /dev/null
+++ b/sys/cmd/rc/code.dep
@@ -0,0 +1,166 @@
+#if 0
+// simple example code
+error
+cd(Args args)
+{
+ switch (args.len) {
+ case 0:
+ errorf("reached cd with no arguments!");
+ return 1;
+ case 1:
+ one:
+ errorf("sh: expected argument to command 'cd'");
+ return 1;
+ case 2:
+ if (args.a[1] == nil)
+ goto one;
+ break;
+ default:
+ errorf("sh: too many arguments to command 'cd'");
+ return 1;
+ }
+ if (chdir(args.a[1]))
+ errorf("cd fail: %s", strerror(errno));
+
+ return 0;
+}
+
+error
+quit(Args args)
+{
+ exit(0);
+}
+
+Builtin builtins[] = {
+ { "cd", cd },
+ { "exit", quit },
+};
+
+void
+clear(Header *arr)
+{
+ arr->len = 0;
+}
+
+int
+readline(Code *code)
+{
+ int n, b;
+
+ n = code->len;
+getchar:
+ if (code->len >= code->cap) {
+ code->cap += 100;
+ code->s = realloc(code->s, code->cap);
+ }
+ /* TODO: unicode? */
+ switch ((b = getchar())) {
+ case EOF:
+ n = -1;
+ goto null;
+ case '\n':
+ n = code->len - n;
+ null:
+ code->s[code->len] = '\0';
+ break;
+ default:
+ code->s[code->len++] = b;
+ goto getchar;
+ }
+
+ return n;
+}
+
+/* TODO: unicode */
+int
+readargs(Code code, Args *args)
+{
+ if (args->a)
+ clear(&args->hdr);
+ else {
+ args->cap += 20;
+ args->a = realloc(args->a, args->cap);
+ }
+
+ args->a[args->len++] = code.s;
+ while (*code.s) {
+ if (!isspace(*code.s++))
+ continue;
+
+ code.s[-1] = '\0';
+ /* consume all remaining space */
+ while (isspace(*code.s))
+ code.s++;
+
+ if (args->len >= args->cap-1) {
+ args->cap += 20;
+ args->a = realloc(args->a, args->cap);
+ }
+ args->a[args->len++] = code.s;
+ }
+ /* nil acts as a sentinel value */
+ args->a[args->len] = nil;
+
+ return args->len;
+}
+
+error
+execute(Args args)
+{
+ int i, status;
+ pid_t cid, wid;
+
+ for (i = 0; i < arrlen(builtins); i++) {
+ if (strcmp(args.a[0], builtins[i].cmd) == 0)
+ return builtins[i].func(args);
+ }
+
+ if ((cid = fork()) == 0) {
+ if (execvp(args.a[0], args.a) == -1)
+ errorf("exec failed: %s", strerror(errno));
+ exit(1);
+ } else if (cid > 0)
+ do
+ wid = waitpid(cid, &status, WUNTRACED);
+ while (!WIFEXITED(status) && !WIFSIGNALED(status));
+ else
+ errorf("fork failed: %s", strerror(errno));
+
+ return status;
+}
+
+static
+void
+flush(void)
+{
+ io·flush(stdout);
+}
+
+static
+void
+prompt(void)
+{
+ printf(";");
+ flush();
+}
+
+int
+main(int argc, char *argv[])
+{
+ int i, err, n;
+ Code code = {0};
+ Args args = {0};
+
+ ARGBEGIN {
+ } ARGEND;
+
+ do {
+ clear(&code.hdr);
+ prompt();
+
+ n = readline(&code);
+ readargs(code, &args);
+ err = execute(args);
+ } while (!err && n > 0);
+}
+#endif