diff options
author | Minijackson <minijackson@riseup.net> | 2018-08-02 10:40:35 +0200 |
---|---|---|
committer | Minijackson <minijackson@riseup.net> | 2018-08-02 10:40:35 +0200 |
commit | eb4c557efa38673eba773bda6b71a286d0c3c3b1 (patch) | |
tree | 570600682e6a21f6f5edefab880ef20f4f298e18 /sinksh/syntaxtree.cpp | |
parent | a24bf3db83d81d7d7677a1f0f750f208d32998a8 (diff) | |
download | sink-eb4c557efa38673eba773bda6b71a286d0c3c3b1.tar.gz sink-eb4c557efa38673eba773bda6b71a286d0c3c3b1.zip |
Add subcommand/parameter/option/flag and automatic help
Diffstat (limited to 'sinksh/syntaxtree.cpp')
-rw-r--r-- | sinksh/syntaxtree.cpp | 98 |
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 | ||
36 | void Syntax::addPositionalArgument(const Argument &argument) | ||
37 | { | ||
38 | arguments.push_back(argument); | ||
39 | } | ||
40 | |||
41 | void Syntax::addParameter(const QString &name, const ParameterOptions &options) | ||
42 | { | ||
43 | parameters.insert(name, options); | ||
44 | } | ||
45 | |||
46 | void Syntax::addFlag(const QString &name, const QString &help) | ||
47 | { | ||
48 | flags.insert(name, help); | ||
49 | } | ||
50 | |||
51 | QString 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 | |||
36 | SyntaxTree::SyntaxTree() | 134 | SyntaxTree::SyntaxTree() |
37 | { | 135 | { |
38 | } | 136 | } |