diff --git a/src/acl/AnnotateClient.cc b/src/acl/AnnotateClient.cc index 1a53fef6116..e1225e61159 100644 --- a/src/acl/AnnotateClient.cc +++ b/src/acl/AnnotateClient.cc @@ -23,12 +23,12 @@ Acl::AnnotateClientCheck::match(ACLChecklist * const ch) const auto conn = checklist->conn(); if (conn) { - tdata->annotate(conn->notes(), &delimiters.value, checklist->al); + tdata->annotate(conn->notes(), delimiters.value(), checklist->al); annotated = true; } if (const auto &request = checklist->request) { - tdata->annotate(request->notes(), &delimiters.value, checklist->al); + tdata->annotate(request->notes(), delimiters.value(), checklist->al); annotated = true; } else if (conn && !conn->pipeline.empty()) { debugs(28, DBG_IMPORTANT, "ERROR: Squid BUG: " << name << " ACL is used in context with " << diff --git a/src/acl/AnnotateTransaction.cc b/src/acl/AnnotateTransaction.cc index 32cb31a5875..51e47517cbc 100644 --- a/src/acl/AnnotateTransaction.cc +++ b/src/acl/AnnotateTransaction.cc @@ -20,7 +20,7 @@ Acl::AnnotateTransactionCheck::match(ACLChecklist * const ch) if (const auto request = checklist->request) { const auto tdata = dynamic_cast(data.get()); assert(tdata); - tdata->annotate(request->notes(), &delimiters.value, checklist->al); + tdata->annotate(request->notes(), delimiters.value(), checklist->al); } else { debugs(28, DBG_IMPORTANT, "WARNING: " << name << " ACL is used in context without " << "current transaction information. Did not annotate."); diff --git a/src/acl/CharacterSetOption.h b/src/acl/CharacterSetOption.h index ddafa9811f9..31c06da36ec 100644 --- a/src/acl/CharacterSetOption.h +++ b/src/acl/CharacterSetOption.h @@ -25,14 +25,15 @@ void TypedOption::import(const SBuf &rawValue) const { SBuf chars = rawValue; // because c_str() is not constant - recipient_->value = CharacterSet(__FILE__, chars.c_str()); + recipient_->setValue(CharacterSet(__FILE__, chars.c_str())); } template <> inline void TypedOption::printValue(std::ostream &os) const { - recipient_->value.printChars(os); // TODO: Quote if needed. + Assure(recipient_->value()); + recipient_->value()->printChars(os); // TODO: Quote if needed. } /// option value to configure one or more characters (e.g., -m=",;") diff --git a/src/acl/Note.cc b/src/acl/Note.cc index cc3f2a23f9f..f3763c4c088 100644 --- a/src/acl/Note.cc +++ b/src/acl/Note.cc @@ -46,7 +46,7 @@ Acl::NoteCheck::match(ACLChecklist * const ch) bool Acl::NoteCheck::matchNotes(const NotePairs *note) const { - const NotePairs::Entries &entries = note->expandListEntries(&delimiters.value); + const NotePairs::Entries &entries = note->expandListEntries(delimiters.value()); for (auto e: entries) if (data->match(e.getRaw())) return true; diff --git a/src/acl/Options.h b/src/acl/Options.h index 2b895d74ea9..3c29a067eb1 100644 --- a/src/acl/Options.h +++ b/src/acl/Options.h @@ -101,14 +101,8 @@ class OptionValue public: typedef Value value_type; - // TODO: Some callers use .value without checking whether the option is - // enabled(), accessing the (default-initialized or customized) default - // value that way. This trick will stop working if we add valued options - // that can be disabled (e.g., --with-foo=x --without-foo). To support such - // options, store the default value separately and provide value accessor. - - OptionValue(): value {} {} - explicit OptionValue(const Value &aValue): value(aValue) {} + OptionValue(): explicitOrDefaultValue {} {} + explicit OptionValue(const Value &aValue): explicitOrDefaultValue(aValue) {} /// whether the option is explicitly turned "on" (with or without a value) bool enabled() const { return configured && !disabled; } @@ -117,11 +111,21 @@ class OptionValue /// go back to the default-initialized state void reset() { *this = OptionValue(); } - Value value; ///< final value storage, possibly after conversions + /// option value (if the option was enabled) or nil (otherwise) + const Value *value() const { return enabled() ? &explicitOrDefaultValue : nullptr; } + void setValue(const Value &aValue){ explicitOrDefaultValue = aValue; }; + bool configured = false; ///< whether the option was present in squid.conf /* flags for configured options */ bool disabled = false; ///< whether the option was turned off bool valued = false; ///< whether a configured option had a value + +private: + /// Value storage after any conversions. + /// For an example of a conversion, \see TypedOption::import(). + /// When `valued` is true, this is an explicitly set value. + /// Otherwise, this is the default value. + Value explicitOrDefaultValue; }; /// a type-specific Option (e.g., a boolean --toggle or -m=SBuf) @@ -191,8 +195,8 @@ class TypedOption: public Option } private: - void import(const SBuf &rawValue) const { recipient_->value = rawValue; } - void printValue(std::ostream &os) const { os << recipient_->value; } + void import(const SBuf &rawValue) const { recipient_->setValue(rawValue); } + void printValue(std::ostream &os) const { os << *recipient_->value(); } // The "mutable" specifier demarcates set-once Option kind/behavior from the // ever-changing recipient of the actual admin-configured option value.