[squid-dev] [PATCH] YesNoNone class updates

Amos Jeffries squid3 at treenet.co.nz
Tue Jan 12 01:36:26 UTC 2016


Update class YesNoNone to use C++11 features which allow better boolean
conversion, assignment, copy, and move ctors.

Distinction is made between implicit and explicit configuration. If the
class is implicitly initialized to some default value it can be used to
test for that value without asserting, but the configured() accessor
indicated false.

Fixes one bug with the enum values where the memset() done to clear the
SquidConfig global settings would set all YesNoNone members to Disabled
instead of Unspecified.

Adds unit tests of the basic class functionality. Though no failure
cases are known yet that can be tested with cppunit, so none of those yet.

Amos
-------------- next part --------------
=== modified file 'src/Makefile.am'
--- src/Makefile.am	2016-01-05 13:00:50 +0000
+++ src/Makefile.am	2016-01-11 17:36:53 +0000
@@ -920,7 +920,8 @@
 	tests/testSBufList \
 	tests/testConfigParser \
 	tests/testStatHist \
-	tests/testLookupTable
+	tests/testLookupTable \
+	tests/testYesNoNone
 
 if HAVE_FS_ROCK
 check_PROGRAMS += tests/testRock
@@ -1010,6 +1011,7 @@
 	tests/stub_access_log.cc \
 	cache_cf.h \
 	YesNoNone.h \
+	tests/stub_YesNoNone.cc \
 	tests/stub_cache_cf.cc \
 	tests/stub_cache_manager.cc \
 	tests/stub_comm.cc \
@@ -1132,6 +1134,7 @@
 	tests/stub_access_log.cc \
 	cache_cf.h \
 	YesNoNone.h \
+	tests/stub_YesNoNone.cc \
 	tests/stub_cache_cf.cc \
 	tests/stub_client_side.cc \
 	tests/stub_debug.cc \
@@ -1583,6 +1586,7 @@
 	tests/stub_acl.cc \
 	cache_cf.h \
 	YesNoNone.h \
+	tests/stub_YesNoNone.cc \
 	tests/stub_cache_cf.cc \
 	tests/stub_cache_manager.cc \
 	tests/stub_client_db.cc \
@@ -2461,6 +2465,7 @@
 	String.cc \
 	cache_cf.h \
 	YesNoNone.h \
+	tests/stub_YesNoNone.cc \
 	$(SBUF_SOURCE) \
 	SBufAlgos.h \
 	SBufAlgos.cc \
@@ -2868,6 +2873,7 @@
 	tests/stub_acl.cc \
 	cache_cf.h \
 	YesNoNone.h \
+	tests/stub_YesNoNone.cc \
 	tests/stub_cache_cf.cc \
 	tests/stub_cache_manager.cc \
 	tests/stub_client_side_request.cc \
@@ -3095,6 +3101,7 @@
 	tests/stub_acl.cc \
 	cache_cf.h \
 	YesNoNone.h \
+	tests/stub_YesNoNone.cc \
 	tests/stub_cache_cf.cc \
 	tests/stub_helper.cc \
 	cbdata.cc \
@@ -3295,6 +3302,7 @@
 	tests/stub_access_log.cc \
 	cache_cf.h \
 	YesNoNone.h \
+	tests/stub_YesNoNone.cc \
 	tests/stub_cache_cf.cc \
 	client_db.h \
 	tests/stub_cache_manager.cc \
@@ -3825,6 +3833,19 @@
 	$(XTRA_LIBS)
 tests_testEnumIterator_DEPENDENCIES =
 
+tests_testYesNoNone_SOURCES = \
+	tests/testYesNoNone.cc \
+	tests/testYesNoNone.h
+nodist_tests_testYesNoNone_SOURCES = \
+	tests/STUB.h \
+	YesNoNone.cc \
+	YesNoNone.h
+tests_testYesNoNone_LDADD= \
+	$(SQUID_CPPUNIT_LIBS) \
+	$(COMPAT_LIB) \
+	$(XTRA_LIBS)
+tests_testYesNoNone_LDFLAGS = $(LIBADD_DL)
+
 TESTS += testHeaders
 
 ## Special Universal .h dependency test script

=== modified file 'src/YesNoNone.cc'
--- src/YesNoNone.cc	2016-01-01 00:12:18 +0000
+++ src/YesNoNone.cc	2016-01-11 20:03:15 +0000
@@ -9,15 +9,30 @@
 #include "squid.h"
 #include "YesNoNone.h"
 
-YesNoNone::operator void*() const
-{
-    assert(option != 0); // must call configure() first
-    return option > 0 ? (void*)this : NULL;
+YesNoNone::YesNoNone(bool beSet):
+    implicit(true)
+{
+    // do not use configure() so implicit remains unchanged.
+    option = beSet ? YesNoNone::optEnabled : YesNoNone::optDisabled;
+}
+
+YesNoNone::operator bool() const
+{
+    assert(option != YesNoNone::optUnspecified);
+    return option == YesNoNone::optEnabled;
+}
+
+bool
+YesNoNone::operator !() const
+{
+    assert(option != YesNoNone::optUnspecified);
+    return option == YesNoNone::optDisabled;
 }
 
 void
 YesNoNone::configure(bool beSet)
 {
-    option = beSet ? +1 : -1;
+    option = beSet ? YesNoNone::optEnabled : YesNoNone::optDisabled;
+    implicit = false;
 }
 

=== modified file 'src/YesNoNone.h'
--- src/YesNoNone.h	2016-01-01 00:12:18 +0000
+++ src/YesNoNone.h	2016-01-11 20:00:23 +0000
@@ -9,27 +9,49 @@
 #ifndef SQUID_YESNONONE_H_
 #define SQUID_YESNONONE_H_
 
-/// Used for boolean enabled/disabled options with complex default logic.
-/// Allows Squid to compute the right default after configuration.
-/// Checks that not-yet-defined option values are not used.
+/**
+ * Used for boolean enabled/disabled options with complex default logic.
+ * Allows Squid to compute the right default after configuration.
+ * Checks that not-yet-defined option values are not used.
+ * Allows for implicit default Yes/No values to be used by initialization
+ * without configuration
+ */
 class YesNoNone
 {
+    // NP: rather odd use of 0 for unset is due to use in SquidConfig
+    // where memset(0) is used to bulk-wipe the settings
+    enum { optDisabled = -1, optUnspecified = 0, optEnabled = 1 };
+
 // TODO: generalize to non-boolean option types
 public:
-    YesNoNone(): option(0) {}
-
-    /// returns true iff enabled; asserts if the option has not been configured
-    operator void *() const; // TODO: use a fancy/safer version of the operator
+    YesNoNone(): option(YesNoNone::optUnspecified), implicit(false) {}
+
+    explicit YesNoNone(bool beSet);
+    YesNoNone &operator =(bool beSet) {configure(beSet); return *this;}
+
+    explicit YesNoNone(const YesNoNone &) = default;
+    YesNoNone &operator =(const YesNoNone &) = default;
+
+    explicit YesNoNone(YesNoNone &&) = default;
+    YesNoNone &operator =(YesNoNone &&) = default;
+
+    ~YesNoNone() = default;
+
+    /// \return true iff enabled; asserts if the option has not been configured
+    explicit operator bool() const;
+
+    /// \return true iff disabled; asserts if the option has not been configured
+    bool operator !() const;
 
     /// enables or disables the option;
     void configure(bool beSet);
 
     /// whether the option was enabled or disabled, by user or Squid
-    bool configured() const { return option != 0; }
+    bool configured() const {return !implicit && option != YesNoNone::optUnspecified;}
 
 private:
-    enum { optUnspecified = -1, optDisabled = 0, optEnabled = 1 };
-    int option; ///< configured value or zero
+    int8_t option; ///< configured value or zero
+    bool implicit; ///< initialized instead of configured
 };
 
 #endif /* SQUID_YESNONONE_H_ */

=== modified file 'src/tests/Stub.list'
--- src/tests/Stub.list	2016-01-01 06:11:55 +0000
+++ src/tests/Stub.list	2016-01-11 15:43:50 +0000
@@ -81,4 +81,5 @@
 	tests/stub_UdsOp.cc \
 	tests/stub_wccp2.cc \
 	tests/stub_whois.cc \
-	tests/stub_wordlist.cc 
+	tests/stub_wordlist.cc \
+	tests/stub_YesNoNone.cc

=== added file 'src/tests/stub_YesNoNone.cc'
--- src/tests/stub_YesNoNone.cc	1970-01-01 00:00:00 +0000
+++ src/tests/stub_YesNoNone.cc	2016-01-12 00:06:32 +0000
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 1996-2016 The Squid Software Foundation and contributors
+ *
+ * Squid software is distributed under GPLv2+ license and includes
+ * contributions from numerous individuals and organizations.
+ * Please see the COPYING and CONTRIBUTORS files for details.
+ */
+
+#include "squid.h"
+
+#define STUB_API "YesNoNone.cc"
+#include "tests/STUB.h"
+
+#include "YesNoNone.h"
+YesNoNone::YesNoNone(bool beSet):implicit(true) {STUB_NOP;}
+YesNoNone::operator bool() const {STUB_NOP; return false;}
+bool YesNoNone::operator !() const {STUB_NOP; return false;}
+void YesNoNone::configure(bool) STUB_NOP

=== modified file 'src/tests/stub_cache_cf.cc'
--- src/tests/stub_cache_cf.cc	2016-01-01 00:12:18 +0000
+++ src/tests/stub_cache_cf.cc	2016-01-11 15:41:09 +0000
@@ -28,5 +28,3 @@
 void ConfigParser::ParseUShort(unsigned short *var) STUB
 void dump_acl_access(StoreEntry * entry, const char *name, acl_access * head) STUB
 void dump_acl_list(StoreEntry*, ACLList*) STUB
-YesNoNone::operator void*() const { STUB_NOP; return NULL; }
-

=== added file 'src/tests/testYesNoNone.cc'
--- src/tests/testYesNoNone.cc	1970-01-01 00:00:00 +0000
+++ src/tests/testYesNoNone.cc	2016-01-11 16:23:22 +0000
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 1996-2016 The Squid Software Foundation and contributors
+ *
+ * Squid software is distributed under GPLv2+ license and includes
+ * contributions from numerous individuals and organizations.
+ * Please see the COPYING and CONTRIBUTORS files for details.
+ */
+
+#include "squid.h"
+#include "tests/testYesNoNone.h"
+#include "unitTestMain.h"
+#include "YesNoNone.h"
+
+#include <stdexcept>
+
+CPPUNIT_TEST_SUITE_REGISTRATION( testYesNoNone );
+
+void
+testYesNoNone::testBasics()
+{
+    // unconfigured, non-implicit
+    {
+        YesNoNone v;
+        CPPUNIT_ASSERT_EQUAL(false, v.configured());
+        // cannot test the value it is 'undefined' and will assert
+    }
+    // implicit dtor test
+
+    // unconfigured, implicit true
+    {
+        YesNoNone v(true);
+        CPPUNIT_ASSERT_EQUAL(false, v.configured());
+        CPPUNIT_ASSERT(v); // bool() operator
+        CPPUNIT_ASSERT_EQUAL(true, static_cast<bool>(v));
+
+        // check explicit setter method
+        v.configure(false);
+        CPPUNIT_ASSERT_EQUAL(true, v.configured());
+        CPPUNIT_ASSERT(!v); // ! operator
+        CPPUNIT_ASSERT_EQUAL(false, static_cast<bool>(v));
+    }
+
+    // unconfigured, implicit false
+    {
+        YesNoNone v(false);
+        CPPUNIT_ASSERT_EQUAL(false, v.configured());
+        CPPUNIT_ASSERT(!v);
+        CPPUNIT_ASSERT_EQUAL(false, static_cast<bool>(v));
+
+        // check assignment operator
+        v = true;
+        CPPUNIT_ASSERT_EQUAL(true, v.configured());
+        CPPUNIT_ASSERT(v);
+        CPPUNIT_ASSERT_EQUAL(true, static_cast<bool>(v));
+    }
+}

=== added file 'src/tests/testYesNoNone.h'
--- src/tests/testYesNoNone.h	1970-01-01 00:00:00 +0000
+++ src/tests/testYesNoNone.h	2016-01-11 10:48:11 +0000
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 1996-2016 The Squid Software Foundation and contributors
+ *
+ * Squid software is distributed under GPLv2+ license and includes
+ * contributions from numerous individuals and organizations.
+ * Please see the COPYING and CONTRIBUTORS files for details.
+ */
+
+#ifndef SQUID_SRC_TESTS_TESTYESNONONE_H
+#define SQUID_SRC_TESTS_TESTYESNONONE_H
+
+#include <cppunit/extensions/HelperMacros.h>
+
+/*
+ * demonstration test file, as new idioms are made they will
+ * be shown in the testYesNoNone source.
+ */
+
+class testYesNoNone : public CPPUNIT_NS::TestFixture
+{
+    CPPUNIT_TEST_SUITE( testYesNoNone );
+    /* note the statement here and then the actual prototype below */
+    CPPUNIT_TEST( testBasics );
+    CPPUNIT_TEST_SUITE_END();
+
+public:
+
+protected:
+    void testBasics();
+};
+
+#endif /* SQUID_SRC_TESTS_TESTYESNONONE_H */
+



More information about the squid-dev mailing list