]> Trent Huber's Code - thus.git/commitdiff
File redirection tokenization
authorTrent Huber <trentmhuber@gmail.com>
Tue, 1 Jul 2025 05:12:24 +0000 (01:12 -0400)
committerTrent Huber <trentmhuber@gmail.com>
Tue, 1 Jul 2025 05:12:24 +0000 (01:12 -0400)
src/input.c
src/lex.c
src/lex.h
src/main.c

index 96b0f79b4b73a9c5ed9d0423d3cf1469d8dc1604..29dc7b139c855292d82915fa25db0970eacf4f7d 100644 (file)
@@ -120,10 +120,11 @@ reset:
    fpurge(stdout);
    push(&history, start);
 
+   *buffer = ';';
    *end = ';';
    *++end = '\0';
 
    signal(SIGCHLD, SIG_DFL);
 
-   return start;
+   return buffer;
 }
index 2843d6552e45b42c991fd53a60c08daa95697c4c..642e2c8213ce1b4390a3665cfca432bbe97d84c8 100644 (file)
--- a/src/lex.c
+++ b/src/lex.c
@@ -1,15 +1,39 @@
 #include <fcntl.h>
 #include <stddef.h>
 #include <stdlib.h>
+#include <err.h>
+#include <stdio.h> // DEBUG
 
 #include "history.h"
 #include "lex.h"
 
-static char *tokens[BUFLEN + 1];
-static struct cmd cmds[1 + (BUFLEN + 1) / 2 + 1] = {{.type = SEMI}};
+static char *tokens[1 + BUFLEN + 1];
+static struct cmd cmds[1 + (BUFLEN + 1) / 2 + 1] = {{.args = tokens, .f = cmds->freds}};
+
+void printfreds(struct cmd *c) {
+   for (; c->f->mode != END; ++c->f) {
+       printf("%d", c->f->newfd);
+       switch (c->f->mode) {
+       case READ:
+           fputs("<", stdout);
+           break;
+       case WRITE:
+           fputs(">", stdout);
+           break;
+       case READWRITE:
+           fputs("<>", stdout);
+           break;
+       case APPEND:
+           fputs(">>", stdout);
+           break;
+       default:;
+       }
+       puts(c->f->old.name);
+   }
+}
 
 struct cmd *lex(char *b) {
-   char **t;
+   char **t, *end;
    struct cmd *c;
    
    if (!b) return NULL;
@@ -17,34 +41,60 @@ struct cmd *lex(char *b) {
    c = cmds;
    while (*b) switch (*b) {
    default:
-       if (!*(b - 1)) {
-           if (c->type) {
-               (++c)->args = t;
-               c->type = NONE;
-           }
+       if (!*(b - 1)) { // Start of a token
+           if (!c->args) c->args = t; // Start of a command
            *t++ = b;
        }
        ++b;
        break;
    case '<':
    case '>':
+       if (*(b - 1)) {
+           if ((c->f->newfd = strtol(*--t, &end, 10)) < 0 || end != b) {
+               warnx("Invalid file redirection operator");
+               c->args = NULL;
+               return c - 1;
+           }
+           if (c->args == t) c->args = NULL;
+       } else c->f->newfd = *b == '>';
+       c->f->mode = *b++;
+       if (*b == '>') {
+           ++b;
+           ++c->f->mode;
+       }
+       c->f++->old.name = b;
+       if (*b == '&') ++b;
        break;
    case '&':
    case '|':
        if (*b == *(b + 1)) *b = '\0';
    case ';':
-       if (c->type == NONE) {
+       if (c->args) {
            *t++ = NULL;
            if (!*b) {
                ++b;
                ++c->type;
            }
            c->type += *b;
+           *(c->f) = (struct fred){0};
+           c->f = c->freds;
+
+           (++c)->args = NULL;
        }
+       c->f = c->freds;
    case ' ':
        *b++ = '\0';
    }
-   *++c = (struct cmd){0};
+   switch (c->type) {
+   case AND:
+   case PIPE:
+   case OR:
+       warnx("Command left open-ended");
+       c->args = NULL;
+       return c - 1;
+   default:
+       *++c = (struct cmd){0};
+   }
 
    return cmds;
 }
index b86549068ca233d9d0d355d33959bb8b76a9b903..f3b26fb26649da05071d32e2aa4b1d2fc4f606ed 100644 (file)
--- a/src/lex.h
+++ b/src/lex.h
@@ -1,5 +1,4 @@
 enum terminator {
-   NONE,
    SEMI = ';',
    BG = '&',
    AND,
@@ -7,21 +6,49 @@ enum terminator {
    OR,
 };
 
+enum mode {
+   END,
+   READ = '<',
+   READWRITE,
+   WRITE = '>',
+   APPEND,
+};
+
+enum type {
+   FD,
+   NAME,
+};
+
+// if (cmd->f->type == NAME) cmd->f->old.fd = open(cmd->f->old.name, mode);
+// dup2(cmd->f->newfd, cmd->f->old.fd);
+// if (cmd->f->type == NAME) close(cmd->f->old.fd);
+// 
+// // vs.
+// 
+// if (*cmd->f->oldfd == '&') fd = open(++cmd->f->oldfd, mode);
+// dup2(cmd->f->newfd, cmd->
+
 struct fred {
-   int newfd, mode;
-   char *oldfd;
+   int newfd;
+   enum mode mode;
+   enum type type;
+   union {
+       int fd;
+       char *name;
+   } old;
 };
 
-/* a>&b -> dup2(b, a); reopen(a, "w");
- * a<&b -> dup2(b, a); reopen(a, "r");
+/* a>&b -> dup2(b, a); reopen(a, "w"); | (1)>&3 -> dup2(3, 1);
+ * a<&b -> dup2(b, a); reopen(a, "r"); | (0)<&3 -> dup2(3, 0);
  * x >a >b >c ...
  */
 
 struct cmd {
    char **args;
    enum terminator type;
+   struct fred *f, freds[(BUFLEN - 1) / 3 + 1];
    int pipe[2];
-   struct fred freds[(BUFLEN - 1) / 3 + 1];
 };
 
+void printfreds(struct cmd *c);
 struct cmd *lex(char *b);
index 2b00fe5bf6fbe3756ac05cb6c7506d31825c36b8..d0904580e8a74ee56db37b6d6748b868d4f4b073 100644 (file)
@@ -44,6 +44,7 @@ int main(void) {
 
    while ((cmd = lex(input()))) {
        while (prev = cmd++, cmd->args) {
+           printfreds(cmd);
            ispipe = cmd->type == PIPE || prev->type == PIPE;
            ispipestart = ispipe && prev->type != PIPE;
            ispipeend = ispipe && cmd->type != PIPE;