Serenity Operating System
1/*
2 * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice, this
9 * list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following disclaimer in the documentation
13 * and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
22 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#pragma once
28
29#include <AK/String.h>
30#include <AK/Vector.h>
31
32struct Redirection {
33 enum Type {
34 Pipe,
35 FileWrite,
36 FileWriteAppend,
37 FileRead,
38 };
39 Type type;
40 int fd { -1 };
41 int rewire_fd { -1 };
42 String path {};
43};
44
45struct Rewiring {
46 int fd { -1 };
47 int rewire_fd { -1 };
48};
49
50struct Subcommand {
51 Vector<String> args;
52 Vector<Redirection> redirections;
53 Vector<Rewiring> rewirings;
54};
55
56struct Command {
57 Vector<Subcommand> subcommands;
58};
59
60class Parser {
61public:
62 explicit Parser(const String& input)
63 : m_input(input)
64 {
65 }
66
67 Vector<Command> parse();
68
69private:
70 enum class AllowEmptyToken { No, Yes };
71 void commit_token(AllowEmptyToken = AllowEmptyToken::No);
72 void commit_subcommand();
73 void commit_command();
74 void do_pipe();
75 void begin_redirect_read(int fd);
76 void begin_redirect_write(int fd);
77
78 enum State {
79 Free,
80 InSingleQuotes,
81 InDoubleQuotes,
82 InWriteAppendOrRedirectionPath,
83 InRedirectionPath,
84 };
85 State m_state { Free };
86 String m_input;
87
88 Vector<Command> m_commands;
89 Vector<Subcommand> m_subcommands;
90 Vector<String> m_tokens;
91 Vector<Redirection> m_redirections;
92 Vector<char> m_token;
93};