Options.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1996-2023 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_SRC_ACL_OPTIONS_H
10 #define SQUID_SRC_ACL_OPTIONS_H
11 
12 #include "acl/forward.h"
13 #include "sbuf/forward.h"
14 
15 #include <iosfwd>
16 #include <vector>
17 
18 // After line continuation is handled by the preprocessor, an Acl::Node object
19 // configuration can be visualized as a sequence of same-name "acl ..." lines:
20 //
21 // L1: acl exampleA typeT parameter1 -i parameter2 parameter3
22 // L2: acl exampleA typeT parameter4
23 // L3: acl exampleA typeT -i -n parameter5 +i parameter6
24 // L4: acl exampleA typeT -n parameter7
25 //
26 // There are two kinds of ACL options (a.k.a. flags):
27 //
28 // * Global (e.g., "-n"): Applies to all parameters regardless of where the
29 // option was discovered/parsed (e.g., "-n" on L3 affects parameter2 on L1).
30 // Declared by Acl::Node class kids (or equivalent) via Acl::Node::options().
31 //
32 // * Line (e.g., "-i"): Applies to the yet unparsed ACL parameters of the
33 // current "acl ..." line (e.g., "-i" on L1 has no effect on parameter4 on L2)
34 // Declared by ACLData class kids (or equivalent) via lineOptions().
35 //
36 // Here is the option:explicitly-affected-parameters map for the above exampleA:
37 // "-n": parameter1-7 (i.e. all parameters)
38 // "-i": parameter2, parameter3; parameter5
39 // "+i": parameter6
40 //
41 // The option name spelling determines the option kind and effect.
42 // Both option kinds use the same general option configuration syntax:
43 // option = name [ '=' value ]
44 // where "name" is option-specific spelling that looks like -x, +x, or --long
45 //
46 // On each "acl ..." line, global options can only appear before the first
47 // parameter, while line options can go before any parameter.
48 //
49 // XXX: The fact that global options affect previous (and subsequent) same-name
50 // "acl name ..." lines surprises and confuses those who comprehend ACLs in
51 // terms of configuration lines (which Squid effectively merges together).
52 
53 namespace Acl {
54 
56 class Option
57 {
58 public:
60  explicit Option(const char *nameThatEnables, const char *nameThatDisables = nullptr, ValueExpectation vex = valueNone);
61  virtual ~Option() {}
62 
65  virtual bool configured() const = 0;
66 
68  virtual void enable() const = 0;
69 
71  virtual void configureWith(const SBuf &rawValue) const = 0;
72 
74  virtual void disable() const = 0;
75 
77  virtual void unconfigure() const = 0;
78 
80  virtual bool disabled() const = 0;
81 
82  virtual bool valued() const = 0;
83 
85  virtual void print(std::ostream &os) const = 0;
86 
88  const char * const onName = nullptr;
89 
92  const char * const offName = nullptr;
93 
95 };
96 
98 template <class Value>
100 {
101 public:
102  typedef Value value_type;
103 
104  // TODO: Some callers use .value without checking whether the option is
105  // enabled(), accessing the (default-initialized or customized) default
106  // value that way. This trick will stop working if we add valued options
107  // that can be disabled (e.g., --with-foo=x --without-foo). To support such
108  // options, store the default value separately and provide value accessor.
109 
111  explicit OptionValue(const Value &aValue): value(aValue) {}
112 
114  bool enabled() const { return configured && !disabled; }
115  explicit operator bool() const { return enabled(); }
116 
118  void reset() { *this = OptionValue<Value>(); }
119 
120  Value value;
121  bool configured = false;
122  /* flags for configured options */
123  bool disabled = false;
124  bool valued = false;
125 };
126 
128 template <class Recipient>
129 class TypedOption: public Option
130 {
131 public:
132  //typedef typename Recipient::value_type value_type;
133  explicit TypedOption(const char *nameThatEnables, const char *nameThatDisables = nullptr, ValueExpectation vex = valueNone):
134  Option(nameThatEnables, nameThatDisables, vex) {}
135 
137  void linkWith(Recipient *recipient) const
138  {
139  assert(recipient);
140  recipient_ = recipient;
141  }
142 
143  /* Option API */
144 
145  bool configured() const override { return recipient_ && recipient_->configured; }
146  bool disabled() const override { return recipient_ && recipient_->disabled && /* paranoid: */ offName; }
147  bool valued() const override { return recipient_ && recipient_->valued; }
148 
149  void unconfigure() const override {
151  recipient_->reset();
152  }
153 
154  void enable() const override
155  {
157  recipient_->configured = true;
158  recipient_->disabled = false;
159  recipient_->valued = false;
160  // leave recipient_->value unchanged
161  }
162 
163  void configureWith(const SBuf &rawValue) const override
164  {
166  recipient_->configured = true;
167  recipient_->disabled = false;
168  recipient_->valued = true;
169  import(rawValue);
170  }
171 
172  void disable() const override
173  {
175  recipient_->configured = true;
176  recipient_->disabled = true;
177  recipient_->valued = false;
178  // leave recipient_->value unchanged
179  }
180 
181  void print(std::ostream &os) const override
182  {
183  if (configured()) {
184  os << ' ' << (disabled() ? offName : onName);
185  if (valued()) {
186  os << '=';
187  printValue(os);
188  }
189  }
190  // else do not report the implicit default
191  }
192 
193 private:
194  void import(const SBuf &rawValue) const { recipient_->value = rawValue; }
195  void printValue(std::ostream &os) const { os << recipient_->value; }
196 
197  // The "mutable" specifier demarcates set-once Option kind/behavior from the
198  // ever-changing recipient of the actual admin-configured option value.
199  mutable Recipient *recipient_ = nullptr;
200 };
201 
202 /* two typical option kinds: --foo and --bar=text */
207 
208 // this specialization should never be called until we start supporting
209 // boolean option values like --name=enable or --name=false
210 template <>
211 inline void
212 BooleanOption::import(const SBuf &) const
213 {
214  assert(!"boolean options do not have ...=values (for now)");
215 }
216 
217 using Options = std::vector<const Option *>;
218 
221 void ParseFlags(const Options &options);
222 
223 /* handy for Class::options() and lineOptions() defaults */
224 const Options &NoOptions();
225 
230 
231 std::ostream &operator <<(std::ostream &, const Option &);
232 std::ostream &operator <<(std::ostream &, const Options &);
233 
234 } // namespace Acl
235 
236 #endif /* SQUID_SRC_ACL_OPTIONS_H */
237 
bool configured() const override
Definition: Options.h:145
OptionValue< bool > BooleanOptionValue
Definition: Options.h:203
Value value
final value storage, possibly after conversions
Definition: Options.h:120
bool valued
whether a configured option had a value
Definition: Options.h:124
a type-specific Option (e.g., a boolean –toggle or -m=SBuf)
Definition: Options.h:129
TypedOption(const char *nameThatEnables, const char *nameThatDisables=nullptr, ValueExpectation vex=valueNone)
Definition: Options.h:133
virtual bool configured() const =0
std::vector< const Option * > Options
Definition: Options.h:217
OptionValue(const Value &aValue)
Definition: Options.h:111
virtual void unconfigure() const =0
clear enable(), configureWith(), or disable() effects
Definition: SBuf.h:93
void printValue(std::ostream &os) const
Definition: Options.h:195
void linkWith(Recipient *recipient) const
who to tell when this option is enabled
Definition: Options.h:137
Definition: Acl.cc:33
virtual void disable() const =0
called after parsing offName (e.g., +i or –disable-x)
void configureWith(const SBuf &rawValue) const override
called after parsing onName and a value (e.g., -x=v or –enable-x=v)
Definition: Options.h:163
const BooleanOption & CaseSensitivityOption()
Definition: Options.cc:241
bool valued() const override
Definition: Options.h:147
void disable() const override
called after parsing offName (e.g., +i or –disable-x)
Definition: Options.h:172
void ParseFlags(const Options &options)
Definition: Options.cc:227
void enable() const override
called after parsing onName without a value (e.g., -x or –enable-x)
Definition: Options.h:154
@ valueNone
Definition: Options.h:59
bool enabled() const
whether the option is explicitly turned "on" (with or without a value)
Definition: Options.h:114
Value value_type
Definition: Options.h:102
A single option supported by an ACL: -x[=value] or –name[=value].
Definition: Options.h:56
virtual ~Option()
Definition: Options.h:61
#define assert(EX)
Definition: assert.h:17
TypedOption< TextOptionValue > TextOption
Definition: Options.h:206
ValueExpectation valueExpectation
expect "=value" part?
Definition: Options.h:94
virtual void enable() const =0
called after parsing onName without a value (e.g., -x or –enable-x)
Recipient * recipient_
parsing results storage
Definition: Options.h:199
const char *const onName
A name that must be used to explicitly enable this Option (required).
Definition: Options.h:88
virtual bool disabled() const =0
whether disable() has been called
bool configured
whether the option was present in squid.conf
Definition: Options.h:121
const Options & NoOptions()
Definition: Options.cc:234
TypedOption< BooleanOptionValue > BooleanOption
Definition: Options.h:205
bool disabled
whether the option was turned off
Definition: Options.h:123
void import(const SBuf &rawValue) const
Definition: Options.h:194
Stores configuration of a typical boolean flag or a single-value Option.
Definition: Options.h:99
virtual void configureWith(const SBuf &rawValue) const =0
called after parsing onName and a value (e.g., -x=v or –enable-x=v)
@ valueOptional
Definition: Options.h:59
ValueExpectation
Definition: Options.h:59
void unconfigure() const override
clear enable(), configureWith(), or disable() effects
Definition: Options.h:149
Option(const char *nameThatEnables, const char *nameThatDisables=nullptr, ValueExpectation vex=valueNone)
Definition: Options.cc:66
OptionValue< SBuf > TextOptionValue
Definition: Options.h:204
const char *const offName
Definition: Options.h:92
virtual bool valued() const =0
@ valueRequired
Definition: Options.h:59
virtual void print(std::ostream &os) const =0
prints a configuration snippet (as an admin could have typed)
void print(std::ostream &os) const override
prints a configuration snippet (as an admin could have typed)
Definition: Options.h:181
std::ostream & operator<<(std::ostream &o, const Answer &a)
Definition: Acl.h:109
bool disabled() const override
whether disable() has been called
Definition: Options.h:146
void reset()
go back to the default-initialized state
Definition: Options.h:118

 

Introduction

Documentation

Support

Miscellaneous