Add the programs ␀ and pack
[minish.git] / src / minish-eval.c
blob9694f576e8fdf46483602c277195e36b7cb582d0
1 #define _POSIX_C_SOURCE 200809L
2 #include <locale.h>
3 #include <stdbool.h>
4 #include <stdint.h>
5 #include <stdlib.h>
6 #include <string.h>
7 #include <unistd.h>
8 #include "ipc.h"
9 #include "try.h"
10 #include "words.h"
12 static Words words;
13 static size_t size_l;
15 static void append(char* const s, size_t const len_r) {
16 if (len_r) {
17 char** const w = words.words + (words.len - 1u);
18 bool const re = size_l;
19 size_t const ll = re ? size_l - 1u : strcspn(*w, "()");
20 out_of_memory_if(SIZE_MAX - ll < len_r + 1u);
21 size_l = ll + len_r + 1u;
22 if (re) {
23 *w = try_realloc(*w, size_l);
24 } else {
25 char* const p = try_malloc(size_l);
26 memcpy(p, *w, ll);
27 *w = p;
29 memcpy(*w + ll, s, len_r);
30 (*w)[size_l - 1u] = '\0';
34 int main(int argc, char** argv) {
35 setlocale(LC_ALL, "");
36 if (argc <= 1) {
37 return 0;
39 argv0 = argv[0];
40 words = new();
41 size_t level = 0u;
42 size_t open_i = 0u;
43 char* open_s = NULL;
44 for (size_t i = 1u; argv[i]; ++i) {
45 if (!level) {
46 push(&words, argv[i]);
47 size_l = 0u;
49 for (char* s = argv[i]; (s = strpbrk(s, "()")); ) {
50 bool const open = *s == '(';
51 *s++ = '\0';
52 if (open && level != SIZE_MAX && !level++) {
53 open_i = i;
54 open_s = s;
55 } else if (!open && level && !--level) {
56 Pipe const p = make_pipe();
57 pid_t const pid = try_fork();
58 if (!pid) {
59 close(p.read);
60 move_fd(p.write, 1);
61 i -= open_i;
62 char** const v = alloc(i + 3u);
63 v[0] = argv[0];
64 v[1] = open_s;
65 v[i + 2u] = NULL;
66 argv += open_i + 1u;
67 i *= sizeof(*v);
68 memcpy(v + 2, argv, i);
69 try_execv(v);
71 close(p.write);
72 ReadWord w = read_word(p.read);
73 append(w.word, w.len);
74 free(w.word);
75 while (!w.eof) {
76 w = read_word(p.read);
77 if (w.word) {
78 push(&words, w.word);
81 close(p.read);
82 wait_script(pid);
83 append(s, strcspn(s, "()"));
87 push(&words, NULL);
88 accept_interactive_signals(true);
89 try_execv(words.words);