1 /**
2  * Copyright (c) 2019, Timothy Stack
3  *
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  *
9  * * Redistributions of source code must retain the above copyright notice, this
10  * list of conditions and the following disclaimer.
11  * * 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  * * Neither the name of Timothy Stack nor the names of its contributors
15  * may be used to endorse or promote products derived from this software
16  * without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ''AS IS'' AND ANY
19  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21  * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
22  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
25  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 #ifndef LNAV_HELP_TEXT_HH
31 #define LNAV_HELP_TEXT_HH
32 
33 #include <map>
34 #include <string>
35 #include <vector>
36 
37 enum class help_context_t {
38     HC_NONE,
39     HC_PARAMETER,
40     HC_RESULT,
41     HC_COMMAND,
42     HC_SQL_COMMAND,
43     HC_SQL_KEYWORD,
44     HC_SQL_INFIX,
45     HC_SQL_FUNCTION,
46     HC_SQL_TABLE_VALUED_FUNCTION,
47 };
48 
49 enum class help_function_type_t {
50     HFT_REGULAR,
51     HFT_AGGREGATE,
52 };
53 
54 enum class help_nargs_t {
55     HN_REQUIRED,
56     HN_OPTIONAL,
57     HN_ZERO_OR_MORE,
58     HN_ONE_OR_MORE,
59 };
60 
61 enum class help_parameter_format_t {
62     HPF_STRING,
63     HPF_REGEX,
64     HPF_INTEGER,
65     HPF_NUMBER,
66     HPF_DATETIME,
67     HPF_ENUM,
68 };
69 
70 struct help_example {
71     const char *he_description{nullptr};
72     const char *he_cmd{nullptr};
73 };
74 
75 struct help_text {
76     help_context_t ht_context{help_context_t::HC_NONE};
77     const char *ht_name{nullptr};
78     const char *ht_summary{nullptr};
79     const char *ht_flag_name{nullptr};
80     const char *ht_group_start{nullptr};
81     const char *ht_group_end{nullptr};
82     const char *ht_description{nullptr};
83     std::vector<struct help_text> ht_parameters;
84     std::vector<struct help_text> ht_results;
85     std::vector<struct help_example> ht_example;
86     help_nargs_t ht_nargs{help_nargs_t::HN_REQUIRED};
87     help_parameter_format_t ht_format{help_parameter_format_t::HPF_STRING};
88     std::vector<const char *> ht_enum_values;
89     std::vector<const char *> ht_tags;
90     std::vector<const char *> ht_opposites;
91     help_function_type_t ht_function_type{help_function_type_t::HFT_REGULAR};
92     void *ht_impl{nullptr};
93 
94     help_text() = default;
95 
help_texthelp_text96     help_text(const char *name, const char *summary = nullptr) noexcept
97         : ht_name(name),
98           ht_summary(summary) {
99         if (name[0] == ':') {
100             this->ht_context = help_context_t::HC_COMMAND;
101             this->ht_name = &name[1];
102         }
103     };
104 
commandhelp_text105     help_text &command() noexcept {
106         this->ht_context = help_context_t::HC_COMMAND;
107         return *this;
108     };
109 
sql_functionhelp_text110     help_text &sql_function() noexcept {
111         this->ht_context = help_context_t::HC_SQL_FUNCTION;
112         return *this;
113     };
114 
sql_agg_functionhelp_text115     help_text &sql_agg_function() noexcept {
116         this->ht_context = help_context_t::HC_SQL_FUNCTION;
117         this->ht_function_type = help_function_type_t::HFT_AGGREGATE;
118         return *this;
119     };
120 
sql_table_valued_functionhelp_text121     help_text &sql_table_valued_function() noexcept {
122         this->ht_context = help_context_t::HC_SQL_TABLE_VALUED_FUNCTION;
123         return *this;
124     };
125 
sql_commandhelp_text126     help_text &sql_command() noexcept {
127         this->ht_context = help_context_t::HC_SQL_COMMAND;
128         return *this;
129     };
130 
sql_keywordhelp_text131     help_text &sql_keyword() noexcept {
132         this->ht_context = help_context_t::HC_SQL_KEYWORD;
133         return *this;
134     };
135 
sql_infixhelp_text136     help_text &sql_infix() noexcept {
137         this->ht_context = help_context_t::HC_SQL_INFIX;
138         return *this;
139     };
140 
with_summaryhelp_text141     help_text &with_summary(const char *summary) noexcept {
142         this->ht_summary = summary;
143         return *this;
144     };
145 
with_flag_namehelp_text146     help_text &with_flag_name(const char *flag) noexcept {
147         this->ht_flag_name = flag;
148         return *this;
149     }
150 
with_groupinghelp_text151     help_text &with_grouping(const char *group_start, const char *group_end) noexcept {
152         this->ht_group_start = group_start;
153         this->ht_group_end = group_end;
154         return *this;
155     }
156 
157     help_text &with_parameters(const std::initializer_list<help_text> &params) noexcept;
158 
159     help_text &with_parameter(const help_text &ht) noexcept;
160 
161     help_text &with_result(const help_text &ht) noexcept;
162 
163     help_text &with_examples(const std::initializer_list<help_example> &examples) noexcept;
164 
165     help_text &with_example(const help_example &example) noexcept;
166 
optionalhelp_text167     help_text &optional() noexcept {
168         this->ht_nargs = help_nargs_t::HN_OPTIONAL;
169         return *this;
170     };
171 
zero_or_morehelp_text172     help_text &zero_or_more() noexcept {
173         this->ht_nargs = help_nargs_t::HN_ZERO_OR_MORE;
174         return *this;
175     };
176 
one_or_morehelp_text177     help_text &one_or_more() noexcept {
178         this->ht_nargs = help_nargs_t::HN_ONE_OR_MORE;
179         return *this;
180     };
181 
with_formathelp_text182     help_text &with_format(help_parameter_format_t format) noexcept {
183         this->ht_format = format;
184         return *this;
185     }
186 
187     help_text &with_enum_values(const std::initializer_list<const char*> &enum_values) noexcept;
188 
189     help_text &with_tags(const std::initializer_list<const char*> &tags) noexcept;
190 
191     help_text &with_opposites(const std::initializer_list<const char*> &opps) noexcept;
192 
193     template<typename F>
with_implhelp_text194     help_text &with_impl(F impl) {
195         this->ht_impl = (void *) impl;
196         return *this;
197     }
198 
199     void index_tags();
200 
201     static std::multimap<std::string, help_text *> TAGGED;
202 };
203 
204 #endif
205