Merge changes from topic "fedora-31"

* changes:
  Switch to Fedora 31 builds
  Fix std::filesystem library linking
diff --git a/src/interpreter.cpp b/src/interpreter.cpp
index 22c1824..f3fde9e 100644
--- a/src/interpreter.cpp
+++ b/src/interpreter.cpp
@@ -127,6 +127,11 @@
         ss << "list";
         break;
     }
+
+    if (!m_datastore.schema()->isConfig(path)) {
+        ss << " (ro)";
+    }
+
     return ss.str();
 }
 
diff --git a/src/schema.hpp b/src/schema.hpp
index 8cdffa1..b8baf34 100644
--- a/src/schema.hpp
+++ b/src/schema.hpp
@@ -54,6 +54,7 @@
     virtual bool isModule(const std::string& name) const = 0;
     virtual bool listHasKey(const schemaPath_& location, const ModuleNodePair& node, const std::string& key) const = 0;
     virtual bool leafIsKey(const std::string& leafPath) const = 0;
+    virtual bool isConfig(const std::string& path) const = 0;
     virtual const std::set<std::string> listKeys(const schemaPath_& location, const ModuleNodePair& node) const = 0;
     virtual yang::TypeInfo leafType(const schemaPath_& location, const ModuleNodePair& node) const = 0;
     virtual yang::TypeInfo leafType(const std::string& path) const = 0;
diff --git a/src/static_schema.cpp b/src/static_schema.cpp
index 6815015..50a6370 100644
--- a/src/static_schema.cpp
+++ b/src/static_schema.cpp
@@ -216,3 +216,8 @@
 {
     throw std::runtime_error{"Internal error: StaticSchema::leafTypeName(std::string) not implemented. The tests should not have called this overload."};
 }
+
+bool StaticSchema::isConfig([[maybe_unused]] const std::string& leafPath) const
+{
+    throw std::runtime_error{"Internal error: StaticSchema::isConfigLeaf(std::string) not implemented. The tests should not have called this overload."};
+}
diff --git a/src/static_schema.hpp b/src/static_schema.hpp
index 8b160b0..554d83a 100644
--- a/src/static_schema.hpp
+++ b/src/static_schema.hpp
@@ -50,6 +50,7 @@
     bool isModule(const std::string& name) const override;
     bool listHasKey(const schemaPath_& location, const ModuleNodePair& node, const std::string& key) const override;
     bool leafIsKey(const std::string& leafPath) const override;
+    bool isConfig(const std::string& leafPath) const override;
     const std::set<std::string> listKeys(const schemaPath_& location, const ModuleNodePair& node) const override;
     yang::TypeInfo leafType(const schemaPath_& location, const ModuleNodePair& node) const override;
     yang::TypeInfo leafType(const std::string& path) const override;
diff --git a/src/yang_schema.cpp b/src/yang_schema.cpp
index 2719bc6..046bfcd 100644
--- a/src/yang_schema.cpp
+++ b/src/yang_schema.cpp
@@ -455,3 +455,8 @@
     auto node = getSchemaNode(path.c_str());
     return node->dsc() ? std::optional{node->dsc()} : std::nullopt;
 }
+
+bool YangSchema::isConfig(const std::string& path) const
+{
+    return getSchemaNode(path.c_str())->flags() & LYS_CONFIG_W;
+}
diff --git a/src/yang_schema.hpp b/src/yang_schema.hpp
index a2981ed..a1b7832 100644
--- a/src/yang_schema.hpp
+++ b/src/yang_schema.hpp
@@ -36,6 +36,7 @@
     bool isModule(const std::string& name) const override;
     bool listHasKey(const schemaPath_& location, const ModuleNodePair& node, const std::string& key) const override;
     bool leafIsKey(const std::string& leafPath) const override;
+    bool isConfig(const std::string& path) const override;
     const std::set<std::string> listKeys(const schemaPath_& location, const ModuleNodePair& node) const override;
     yang::TypeInfo leafType(const schemaPath_& location, const ModuleNodePair& node) const override;
     yang::TypeInfo leafType(const std::string& path) const override;
diff --git a/tests/yang.cpp b/tests/yang.cpp
index 941586d..a458909 100644
--- a/tests/yang.cpp
+++ b/tests/yang.cpp
@@ -354,6 +354,18 @@
         }
     }
 
+    leaf clockSpeed {
+        type int64;
+        config false;
+    }
+
+    container systemStats {
+        config false;
+        leaf upTime {
+            type uint64;
+        }
+    }
+
 })";
 
 namespace std {
@@ -762,7 +774,9 @@
                        "example-schema:portSettings",
                        "example-schema:portMapping",
                        "example-schema:activeMappedPort",
-                       "example-schema:activePort"};
+                       "example-schema:activePort",
+                       "example-schema:clockSpeed",
+                       "example-schema:systemStats"};
             }
 
             SECTION("example-schema:a")
@@ -916,6 +930,144 @@
         {
             REQUIRE(ys.leafrefPath("/example-schema:activeNumber") == "/example-schema:_list/number");
         }
+
+        SECTION("isConfig")
+        {
+            REQUIRE(ys.isConfig("/example-schema:leafInt32"));
+            REQUIRE_FALSE(ys.isConfig("/example-schema:clockSpeed"));
+            REQUIRE_FALSE(ys.isConfig("/example-schema:systemStats"));
+            REQUIRE_FALSE(ys.isConfig("/example-schema:systemStats/upTime"));
+        }
+
+        SECTION("moduleNodes")
+        {
+            std::string module;
+            std::set<std::string> expectedNonRecursive;
+            std::set<std::string> expectedRecursive;
+            SECTION("example-schema")
+            {
+                module = "example-schema";
+                expectedNonRecursive = {
+                    "example-schema:_list",
+                    "example-schema:a",
+                    "example-schema:activeMappedPort",
+                    "example-schema:activeNumber",
+                    "example-schema:activePort",
+                    "example-schema:another-duration",
+                    "example-schema:b",
+                    "example-schema:carry",
+                    "example-schema:clockSpeed",
+                    "example-schema:direction",
+                    "example-schema:duration",
+                    "example-schema:ethernet",
+                    "example-schema:foodDrinkIdentLeaf",
+                    "example-schema:foodIdentLeaf",
+                    "example-schema:interrupt",
+                    "example-schema:leafBool",
+                    "example-schema:leafDecimal",
+                    "example-schema:leafEnum",
+                    "example-schema:leafEnumTypedef",
+                    "example-schema:leafEnumTypedefRestricted",
+                    "example-schema:leafEnumTypedefRestricted2",
+                    "example-schema:leafInt16",
+                    "example-schema:leafInt32",
+                    "example-schema:leafInt64",
+                    "example-schema:leafInt8",
+                    "example-schema:leafString",
+                    "example-schema:leafUint16",
+                    "example-schema:leafUint32",
+                    "example-schema:leafUint64",
+                    "example-schema:leafUint8",
+                    "example-schema:length",
+                    "example-schema:loopback",
+                    "example-schema:myRpc",
+                    "example-schema:numberOrString",
+                    "example-schema:pizzaIdentLeaf",
+                    "example-schema:pizzaSize",
+                    "example-schema:portMapping",
+                    "example-schema:portSettings",
+                    "example-schema:systemStats",
+                    "example-schema:twoKeyList",
+                    "example-schema:wavelength",
+                    "example-schema:zero"
+                };
+                expectedRecursive = {
+                    "/example-schema:_list",
+                    "/example-schema:_list/contInList",
+                    "/example-schema:_list/number",
+                    "/example-schema:a",
+                    "/example-schema:a/a2",
+                    "/example-schema:a/a2/a3",
+                    "/example-schema:a/leafa",
+                    "/example-schema:a/second-schema:augmentedContainer",
+                    "/example-schema:activeMappedPort",
+                    "/example-schema:activeNumber",
+                    "/example-schema:activePort",
+                    "/example-schema:another-duration",
+                    "/example-schema:b",
+                    "/example-schema:b/b2",
+                    "/example-schema:b/b2/b3",
+                    "/example-schema:carry",
+                    "/example-schema:clockSpeed",
+                    "/example-schema:direction",
+                    "/example-schema:duration",
+                    "/example-schema:foodDrinkIdentLeaf",
+                    "/example-schema:foodIdentLeaf",
+                    "/example-schema:interface/caseEthernet/ethernet",
+                    "/example-schema:interface/caseEthernet/ethernet/ip",
+                    "/example-schema:interface/caseLoopback/loopback",
+                    "/example-schema:interface/caseLoopback/loopback/ip",
+                    "/example-schema:interrupt",
+                    "/example-schema:leafBool",
+                    "/example-schema:leafDecimal",
+                    "/example-schema:leafEnum",
+                    "/example-schema:leafEnumTypedef",
+                    "/example-schema:leafEnumTypedefRestricted",
+                    "/example-schema:leafEnumTypedefRestricted2",
+                    "/example-schema:leafInt16",
+                    "/example-schema:leafInt32",
+                    "/example-schema:leafInt64",
+                    "/example-schema:leafInt8",
+                    "/example-schema:leafString",
+                    "/example-schema:leafUint16",
+                    "/example-schema:leafUint32",
+                    "/example-schema:leafUint64",
+                    "/example-schema:leafUint8",
+                    "/example-schema:length",
+                    "/example-schema:myRpc",
+                    "/example-schema:myRpc/input",
+                    "/example-schema:myRpc/output",
+                    "/example-schema:numberOrString",
+                    "/example-schema:pizzaIdentLeaf",
+                    "/example-schema:pizzaSize",
+                    "/example-schema:portMapping",
+                    "/example-schema:portMapping/port",
+                    "/example-schema:portSettings",
+                    "/example-schema:portSettings/port",
+                    "/example-schema:systemStats",
+                    "/example-schema:systemStats/upTime",
+                    "/example-schema:twoKeyList",
+                    "/example-schema:twoKeyList/name",
+                    "/example-schema:twoKeyList/number",
+                    "/example-schema:wavelength",
+                    "/example-schema:zero"
+                };
+            }
+
+            SECTION("second-schema")
+            {
+                module = "second-schema";
+                expectedNonRecursive = {
+                    "second-schema:bla"
+                };
+                expectedRecursive = {
+                    "/second-schema:bla", "/second-schema:bla/bla2"
+                };
+            }
+
+            REQUIRE(ys.moduleNodes(module_{module}, Recursion::NonRecursive) == expectedNonRecursive);
+            REQUIRE(ys.moduleNodes(module_{module}, Recursion::Recursive) == expectedRecursive);
+        }
     }
 
     SECTION("negative")