]> git.ipfire.org Git - thirdparty/squid.git/blob - src/acl/Options.h
Support for --long-acl-options
[thirdparty/squid.git] / src / acl / Options.h
1 /*
2 * Copyright (C) 1996-2017 The Squid Software Foundation and contributors
3 *
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
7 */
8
9 #ifndef SQUID_ACL_OPTIONS_H
10 #define SQUID_ACL_OPTIONS_H
11
12 #include "acl/forward.h"
13 #include "sbuf/forward.h"
14
15 #include <iosfwd>
16 #include <map>
17 #include <set>
18
19 // After all same-name acl configuration lines are merged into one ACL:
20 // configuration = acl name type [option...] [[flag...] parameter...]
21 // option = -x[=value] | --name[=value]
22 // flag = option
23 //
24 // Options and flags use the same syntax, but differ in scope and handling code:
25 // * ACL options appear before all parameters and apply to all parameters.
26 // They are handled by ACL kids (or equivalent).
27 // * Parameter flags may appear after some other parameters and apply only to
28 // the subsequent parameters (until they are overwritten by later flags).
29 // They are handled by ACLData kids.
30 // ACL options parsing code skips and leaves leading parameter flags (if any)
31 // for ACLData code to process.
32
33 namespace Acl {
34
35 typedef const char *OptionName;
36
37 /// A single option supported by an ACL: -x[=value] or --name[=value]
38 /// Unlike a parameter flag, this option applies to all ACL parameters.
39 class Option
40 {
41 public:
42 typedef enum { valueNone, valueOptional, valueRequired } ValueExpectation;
43 explicit Option(ValueExpectation vex = valueNone): valueExpectation(vex) {}
44 virtual ~Option() {}
45
46 /// whether the admin explicitly specified this option
47 /// (i.e., whether configureWith() or configureDefault() has been called)
48 virtual bool configured() const = 0;
49
50 /// called after parsing -x or --name
51 virtual void configureDefault() const = 0;
52
53 /// called after parsing -x=value or --name=value
54 virtual void configureWith(const SBuf &rawValue) const = 0;
55
56 virtual bool valued() const = 0;
57
58 /// prints a configuration snippet (as an admin could have typed)
59 virtual void print(std::ostream &os) const = 0;
60
61 ValueExpectation valueExpectation = valueNone; ///< expect "=value" part?
62 };
63
64 /// Stores configuration of a typical boolean flag or a single-value Option.
65 template <class Value>
66 class OptionValue
67 {
68 public:
69 typedef Value value_type;
70
71 OptionValue(): value {} {}
72 explicit OptionValue(const Value &aValue): value(aValue) {}
73
74 explicit operator bool() const { return configured; }
75
76 Value value; ///< final value storage, possibly after conversions
77 bool configured = false; ///< whether the option was present in squid.conf
78 bool valued = false; ///< whether a configured option had a value
79 };
80
81 /// a type-specific Option (e.g., a boolean --toggle or -m=SBuf)
82 template <class Recipient>
83 class TypedOption: public Option
84 {
85 public:
86 //typedef typename Recipient::value_type value_type;
87 explicit TypedOption(ValueExpectation vex = valueNone): Option(vex) {}
88
89 /// who to tell when this option is enabled
90 void linkWith(Recipient *recipient) const
91 {
92 assert(recipient);
93 recipient_ = recipient;
94 }
95
96 /* Option API */
97
98 virtual bool configured() const override { return recipient_ && recipient_->configured; }
99 virtual bool valued() const override { return recipient_ && recipient_->valued; }
100
101 /// sets the default value when option is used without a value
102 virtual void configureDefault() const override
103 {
104 assert(recipient_);
105 recipient_->configured = true;
106 recipient_->valued = false;
107 // sets recipient_->value to default
108 setDefault();
109 }
110
111 /// sets the option value from rawValue
112 virtual void configureWith(const SBuf &rawValue) const override
113 {
114 assert(recipient_);
115 recipient_->configured = true;
116 recipient_->valued = true;
117 import(rawValue);
118 }
119
120 virtual void print(std::ostream &os) const override { if (valued()) os << recipient_->value; }
121
122 private:
123 void import(const SBuf &rawValue) const { recipient_->value = rawValue; }
124 void setDefault() const { /*leave recipient_->value as is*/}
125
126 // The "mutable" specifier demarcates set-once Option kind/behavior from the
127 // ever-changing recipient of the actual admin-configured option value.
128 mutable Recipient *recipient_ = nullptr; ///< parsing results storage
129 };
130
131 /* two typical option kinds: --foo and --bar=text */
132 typedef OptionValue<bool> BooleanOptionValue;
133 typedef OptionValue<SBuf> TextOptionValue;
134 typedef TypedOption<BooleanOptionValue> BooleanOption;
135 typedef TypedOption<TextOptionValue> TextOption;
136
137 // this specialization should never be called until we start supporting
138 // boolean option values like --name=enable or --name=false
139 template <>
140 inline void
141 BooleanOption::import(const SBuf &) const
142 {
143 assert(!"boolean options do not have ...=values (for now)");
144 }
145
146 template <>
147 inline void
148 BooleanOption::setDefault() const
149 {
150 recipient_->value = true;
151 }
152
153 /// option name comparison functor
154 class OptionNameCmp {
155 public:
156 bool operator()(const OptionName a, const OptionName b) const;
157 };
158 /// name:option map
159 typedef std::map<OptionName, const Option*, OptionNameCmp> Options;
160
161 /// a set of parameter flag names
162 typedef std::set<OptionName, OptionNameCmp> ParameterFlags;
163
164 /// parses the flags part of the being-parsed ACL, filling Option values
165 /// \param options options supported by the ACL as a whole (e.g., -n)
166 /// \param flags options supported by ACL parameter(s) (e.g., -i)
167 void ParseFlags(const Options &options, const ParameterFlags &flags);
168
169 /* handy for Class::options() and Class::supportedFlags() defaults */
170 const Options &NoOptions(); ///< \returns an empty Options container
171 const ParameterFlags &NoFlags(); ///< \returns an empty ParameterFlags container
172
173 } // namespace Acl
174
175 std::ostream &operator <<(std::ostream &os, const Acl::Option &option);
176 std::ostream &operator <<(std::ostream &os, const Acl::Options &options);
177
178 #endif /* SQUID_ACL_OPTIONS_H */
179