summaryrefslogtreecommitdiffstats
path: root/sinksh/syntaxtree.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'sinksh/syntaxtree.cpp')
-rw-r--r--sinksh/syntaxtree.cpp98
1 files changed, 98 insertions, 0 deletions
diff --git a/sinksh/syntaxtree.cpp b/sinksh/syntaxtree.cpp
index 0eb9782..fea99ef 100644
--- a/sinksh/syntaxtree.cpp
+++ b/sinksh/syntaxtree.cpp
@@ -33,6 +33,104 @@ Syntax::Syntax(const QString &k, const QString &helpText, std::function<bool(con
33{ 33{
34} 34}
35 35
36void Syntax::addPositionalArgument(const Argument &argument)
37{
38 arguments.push_back(argument);
39}
40
41void Syntax::addParameter(const QString &name, const ParameterOptions &options)
42{
43 parameters.insert(name, options);
44}
45
46void Syntax::addFlag(const QString &name, const QString &help)
47{
48 flags.insert(name, help);
49}
50
51QString Syntax::usage() const
52{
53 // TODO: refactor into meaningful functions?
54 bool hasArguments = !arguments.isEmpty();
55 bool hasFlags = !flags.isEmpty();
56 bool hasOptions = !parameters.isEmpty();
57 bool hasSubcommand = !children.isEmpty();
58
59 QString argumentsSummary;
60
61 QString argumentsUsage;
62 if (hasArguments) {
63 argumentsUsage += "\nARGUMENTS:\n";
64 for (const auto &arg : arguments) {
65 if (arg.required) {
66 argumentsSummary += QString(" <%1>").arg(arg.name);
67 argumentsUsage += QString(" <%1>: %2\n").arg(arg.name).arg(arg.help);
68 } else {
69 argumentsSummary += QString(" [%1]").arg(arg.name);
70 argumentsUsage += QString(" [%1]: %2\n").arg(arg.name).arg(arg.help);
71 }
72 if (arg.variadic) {
73 argumentsSummary += "...";
74 }
75 }
76 }
77
78 if (hasFlags) {
79 argumentsSummary += " [FLAGS]";
80 }
81
82 if (hasOptions) {
83 argumentsSummary += " [OPTIONS]";
84 }
85
86 if (hasSubcommand) {
87 if (hasArguments || hasFlags || hasOptions) {
88 argumentsSummary = QString(" [ <SUB-COMMAND> |%1 ]").arg(argumentsSummary);
89 } else {
90 argumentsSummary = " <SUB-COMMAND>";
91 }
92 }
93
94 argumentsSummary += '\n';
95
96 QString subcommandsUsage;
97 if (hasSubcommand) {
98 subcommandsUsage += "\nSUB-COMMANDS:\n"
99 " Use the 'help' command to find out more about a sub-command.\n\n";
100 for (const auto &command : children) {
101 subcommandsUsage += QString(" %1: %2\n").arg(command.keyword).arg(command.help);
102 }
103 }
104
105 QString flagsUsage;
106 if (hasFlags) {
107 flagsUsage += "\nFLAGS:\n";
108 for (auto it = flags.constBegin(); it != flags.constEnd(); ++it) {
109 flagsUsage += QString(" [--%1]: %2\n").arg(it.key()).arg(it.value());
110 }
111 }
112
113 QString optionsUsage;
114 if (hasOptions) {
115 optionsUsage += "\nOPTIONS:\n";
116 for (auto it = parameters.constBegin(); it != parameters.constEnd(); ++it) {
117 optionsUsage += " ";
118 if (!it.value().required) {
119 optionsUsage += QString("[--%1 $%2]").arg(it.key()).arg(it.value().name);
120 } else {
121 optionsUsage += QString("<--%1 $%2>").arg(it.key()).arg(it.value().name);
122 }
123
124 optionsUsage += ": " + it.value().help + '\n';
125 }
126 }
127
128 // TODO: instead of just the keyword, we might want to have the whole
129 // command (e.g. if this is a sub-command)
130 return QString("USAGE:\n ") + keyword + argumentsSummary + subcommandsUsage +
131 argumentsUsage + flagsUsage + optionsUsage;
132}
133
36SyntaxTree::SyntaxTree() 134SyntaxTree::SyntaxTree()
37{ 135{
38} 136}