data tree FEATURE support for lists with duplicate instances
Changes mainly in diff processing.
Refs #1483
diff --git a/models/yang@2020-06-17.h b/models/yang@2020-06-17.h
deleted file mode 100644
index 4c5058e..0000000
--- a/models/yang@2020-06-17.h
+++ /dev/null
@@ -1,377 +0,0 @@
-unsigned char yang_2020_06_17_yang[] = {
- 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x20, 0x79, 0x61, 0x6e, 0x67, 0x20,
- 0x7b, 0x0a, 0x20, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63,
- 0x65, 0x20, 0x22, 0x75, 0x72, 0x6e, 0x3a, 0x69, 0x65, 0x74, 0x66, 0x3a,
- 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x3a, 0x78, 0x6d, 0x6c, 0x3a, 0x6e,
- 0x73, 0x3a, 0x79, 0x61, 0x6e, 0x67, 0x3a, 0x31, 0x22, 0x3b, 0x0a, 0x20,
- 0x20, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x20, 0x79, 0x61, 0x6e, 0x67,
- 0x3b, 0x0a, 0x0a, 0x20, 0x20, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x20,
- 0x69, 0x65, 0x74, 0x66, 0x2d, 0x79, 0x61, 0x6e, 0x67, 0x2d, 0x6d, 0x65,
- 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20,
- 0x20, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x20, 0x6d, 0x64, 0x3b, 0x0a,
- 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e,
- 0x2d, 0x64, 0x61, 0x74, 0x65, 0x20, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30,
- 0x38, 0x2d, 0x30, 0x35, 0x3b, 0x0a, 0x20, 0x20, 0x7d, 0x0a, 0x0a, 0x20,
- 0x20, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f,
- 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, 0x6c, 0x69, 0x62, 0x79, 0x61,
- 0x6e, 0x67, 0x22, 0x3b, 0x0a, 0x0a, 0x20, 0x20, 0x63, 0x6f, 0x6e, 0x74,
- 0x61, 0x63, 0x74, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, 0x57, 0x65, 0x62,
- 0x3a, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a,
- 0x2f, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d,
- 0x2f, 0x43, 0x45, 0x53, 0x4e, 0x45, 0x54, 0x2f, 0x6c, 0x69, 0x62, 0x79,
- 0x61, 0x6e, 0x67, 0x2f, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x41,
- 0x75, 0x74, 0x68, 0x6f, 0x72, 0x3a, 0x20, 0x52, 0x61, 0x64, 0x65, 0x6b,
- 0x20, 0x4b, 0x72, 0x65, 0x6a, 0x63, 0x69, 0x20, 0x3c, 0x72, 0x6b, 0x72,
- 0x65, 0x6a, 0x63, 0x69, 0x40, 0x63, 0x65, 0x73, 0x6e, 0x65, 0x74, 0x2e,
- 0x63, 0x7a, 0x3e, 0x22, 0x3b, 0x0a, 0x0a, 0x20, 0x20, 0x64, 0x65, 0x73,
- 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x20, 0x20, 0x20,
- 0x20, 0x22, 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20,
- 0x6b, 0x69, 0x6e, 0x64, 0x20, 0x6f, 0x66, 0x20, 0x66, 0x61, 0x6b, 0x65,
- 0x20, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20,
- 0x6e, 0x6f, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2c, 0x20, 0x74, 0x79, 0x70,
- 0x65, 0x64, 0x65, 0x66, 0x73, 0x20, 0x6f, 0x72, 0x20, 0x61, 0x6e, 0x79,
- 0x74, 0x68, 0x69, 0x6e, 0x67, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65,
- 0x6c, 0x73, 0x65, 0x2e, 0x20, 0x6c, 0x69, 0x62, 0x79, 0x61, 0x6e, 0x67,
- 0x20, 0x75, 0x73, 0x65, 0x73, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x6d,
- 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x69, 0x6d, 0x70,
- 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x76, 0x61, 0x72, 0x69, 0x6f,
- 0x75, 0x73, 0x20, 0x59, 0x41, 0x4e, 0x47, 0x20, 0x61, 0x74, 0x74, 0x72,
- 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
- 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x52,
- 0x46, 0x43, 0x20, 0x36, 0x30, 0x32, 0x30, 0x2e, 0x22, 0x3b, 0x0a, 0x0a,
- 0x20, 0x20, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x32,
- 0x30, 0x32, 0x30, 0x2d, 0x30, 0x36, 0x2d, 0x31, 0x37, 0x20, 0x7b, 0x0a,
- 0x20, 0x20, 0x20, 0x20, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74,
- 0x69, 0x6f, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x41,
- 0x64, 0x64, 0x65, 0x64, 0x20, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74,
- 0x61, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x64, 0x69, 0x66, 0x66, 0x2e, 0x22,
- 0x3b, 0x0a, 0x20, 0x20, 0x7d, 0x0a, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x76,
- 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x32, 0x30, 0x31, 0x37, 0x2d, 0x30,
- 0x32, 0x2d, 0x32, 0x30, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x64,
- 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x41, 0x64, 0x64, 0x65, 0x64, 0x20,
- 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x20, 0x66, 0x6f, 0x72,
- 0x20, 0x4e, 0x45, 0x54, 0x43, 0x4f, 0x4e, 0x46, 0x27, 0x73, 0x20, 0x65,
- 0x64, 0x69, 0x74, 0x2d, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x20, 0x6d,
- 0x61, 0x6e, 0x69, 0x70, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20,
- 0x77, 0x69, 0x74, 0x68, 0x20, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x65, 0x64,
- 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x69, 0x73, 0x74,
- 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6c, 0x65, 0x61, 0x66, 0x2d, 0x6c,
- 0x69, 0x73, 0x74, 0x73, 0x2e, 0x22, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20,
- 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x0a, 0x20, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x22, 0x52, 0x46, 0x43, 0x20, 0x37, 0x39, 0x35,
- 0x30, 0x3a, 0x20, 0x54, 0x68, 0x65, 0x20, 0x59, 0x41, 0x4e, 0x47, 0x20,
- 0x31, 0x2e, 0x31, 0x20, 0x44, 0x61, 0x74, 0x61, 0x20, 0x4d, 0x6f, 0x64,
- 0x65, 0x6c, 0x69, 0x6e, 0x67, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x75, 0x61,
- 0x67, 0x65, 0x22, 0x3b, 0x0a, 0x20, 0x20, 0x7d, 0x0a, 0x0a, 0x20, 0x20,
- 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x32, 0x30, 0x31,
- 0x36, 0x2d, 0x30, 0x32, 0x2d, 0x31, 0x31, 0x20, 0x7b, 0x0a, 0x20, 0x20,
- 0x20, 0x20, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f,
- 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x49, 0x6e, 0x69,
- 0x74, 0x69, 0x61, 0x6c, 0x20, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f,
- 0x6e, 0x22, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x66, 0x65,
- 0x72, 0x65, 0x6e, 0x63, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
- 0x22, 0x52, 0x46, 0x43, 0x20, 0x36, 0x30, 0x32, 0x30, 0x3a, 0x20, 0x59,
- 0x41, 0x4e, 0x47, 0x20, 0x2d, 0x20, 0x41, 0x20, 0x44, 0x61, 0x74, 0x61,
- 0x20, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x69, 0x6e, 0x67, 0x20, 0x4c, 0x61,
- 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x0a, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x68, 0x65, 0x20, 0x4e, 0x65,
- 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x20, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
- 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x50, 0x72, 0x6f, 0x74,
- 0x6f, 0x63, 0x6f, 0x6c, 0x20, 0x28, 0x4e, 0x45, 0x54, 0x43, 0x4f, 0x4e,
- 0x46, 0x29, 0x22, 0x3b, 0x0a, 0x20, 0x20, 0x7d, 0x0a, 0x0a, 0x20, 0x20,
- 0x6d, 0x64, 0x3a, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f,
- 0x6e, 0x20, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x20, 0x7b, 0x0a, 0x20,
- 0x20, 0x20, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x65, 0x6e, 0x75, 0x6d,
- 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x7b, 0x0a, 0x20, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x75, 0x6d, 0x20, 0x66, 0x69, 0x72,
- 0x73, 0x74, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e,
- 0x75, 0x6d, 0x20, 0x6c, 0x61, 0x73, 0x74, 0x3b, 0x0a, 0x20, 0x20, 0x20,
- 0x20, 0x20, 0x20, 0x65, 0x6e, 0x75, 0x6d, 0x20, 0x62, 0x65, 0x66, 0x6f,
- 0x72, 0x65, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e,
- 0x75, 0x6d, 0x20, 0x61, 0x66, 0x74, 0x65, 0x72, 0x3b, 0x0a, 0x20, 0x20,
- 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x66, 0x65,
- 0x72, 0x65, 0x6e, 0x63, 0x65, 0x20, 0x22, 0x52, 0x46, 0x43, 0x37, 0x39,
- 0x35, 0x30, 0x20, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x37,
- 0x2e, 0x38, 0x2e, 0x36, 0x2e, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x65,
- 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x37, 0x2e, 0x37, 0x2e, 0x39, 0x2e,
- 0x22, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x64, 0x65, 0x73, 0x63, 0x72,
- 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
- 0x20, 0x22, 0x49, 0x6e, 0x20, 0x75, 0x73, 0x65, 0x72, 0x20, 0x6f, 0x72,
- 0x64, 0x65, 0x72, 0x65, 0x64, 0x20, 0x6c, 0x65, 0x61, 0x66, 0x2d, 0x6c,
- 0x69, 0x73, 0x74, 0x2c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x74, 0x74,
- 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x62,
- 0x65, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x63, 0x6f,
- 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
- 0x20, 0x77, 0x68, 0x65, 0x72, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68,
- 0x65, 0x20, 0x6c, 0x65, 0x61, 0x66, 0x2d, 0x6c, 0x69, 0x73, 0x74, 0x20,
- 0x74, 0x68, 0x65, 0x20, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x20, 0x69, 0x73,
- 0x20, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x65, 0x64, 0x2e, 0x20, 0x49,
- 0x74, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x62, 0x65, 0x20, 0x75, 0x73, 0x65,
- 0x64, 0x20, 0x64, 0x75, 0x72, 0x69, 0x6e, 0x67, 0x0a, 0x20, 0x20, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x74, 0x68, 0x65, 0x20, 0x4e, 0x45, 0x54, 0x43,
- 0x4f, 0x4e, 0x46, 0x20, 0x3c, 0x65, 0x64, 0x69, 0x74, 0x2d, 0x63, 0x6f,
- 0x6e, 0x66, 0x69, 0x67, 0x3e, 0x20, 0x5c, 0x22, 0x63, 0x72, 0x65, 0x61,
- 0x74, 0x65, 0x5c, 0x22, 0x20, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69,
- 0x6f, 0x6e, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x69, 0x6e, 0x73, 0x65, 0x72,
- 0x74, 0x20, 0x61, 0x20, 0x6e, 0x65, 0x77, 0x20, 0x6c, 0x69, 0x73, 0x74,
- 0x20, 0x6f, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c,
- 0x65, 0x61, 0x66, 0x2d, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x65, 0x6e, 0x74,
- 0x72, 0x79, 0x2c, 0x20, 0x6f, 0x72, 0x20, 0x64, 0x75, 0x72, 0x69, 0x6e,
- 0x67, 0x20, 0x5c, 0x22, 0x6d, 0x65, 0x72, 0x67, 0x65, 0x5c, 0x22, 0x20,
- 0x6f, 0x72, 0x20, 0x5c, 0x22, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65,
- 0x5c, 0x22, 0x20, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e,
- 0x73, 0x20, 0x74, 0x6f, 0x20, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x0a,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x20, 0x6e, 0x65, 0x77,
- 0x20, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x6f, 0x72, 0x20, 0x6c, 0x65, 0x61,
- 0x66, 0x2d, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x65, 0x6e, 0x74, 0x72, 0x79,
- 0x20, 0x6f, 0x72, 0x20, 0x6d, 0x6f, 0x76, 0x65, 0x20, 0x61, 0x6e, 0x20,
- 0x65, 0x78, 0x69, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x6f, 0x6e, 0x65,
- 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x49, 0x66,
- 0x20, 0x74, 0x68, 0x65, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x69,
- 0x73, 0x20, 0x5c, 0x22, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x5c, 0x22,
- 0x20, 0x6f, 0x72, 0x20, 0x5c, 0x22, 0x61, 0x66, 0x74, 0x65, 0x72, 0x5c,
- 0x22, 0x2c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x5c, 0x22, 0x76, 0x61, 0x6c,
- 0x75, 0x65, 0x5c, 0x22, 0x2f, 0x5c, 0x22, 0x6b, 0x65, 0x79, 0x5c, 0x22,
- 0x20, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x0a, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4d, 0x55, 0x53, 0x54, 0x20, 0x61,
- 0x6c, 0x73, 0x6f, 0x20, 0x62, 0x65, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20,
- 0x74, 0x6f, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x79, 0x20, 0x61,
- 0x6e, 0x20, 0x65, 0x78, 0x69, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x65,
- 0x6e, 0x74, 0x72, 0x79, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20,
- 0x6c, 0x69, 0x73, 0x74, 0x20, 0x6f, 0x72, 0x20, 0x6c, 0x65, 0x61, 0x66,
- 0x2d, 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20,
- 0x20, 0x20, 0x20, 0x49, 0x66, 0x20, 0x6e, 0x6f, 0x20, 0x5c, 0x22, 0x69,
- 0x6e, 0x73, 0x65, 0x72, 0x74, 0x5c, 0x22, 0x20, 0x61, 0x74, 0x74, 0x72,
- 0x69, 0x62, 0x75, 0x74, 0x65, 0x20, 0x69, 0x73, 0x20, 0x70, 0x72, 0x65,
- 0x73, 0x65, 0x6e, 0x74, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20,
- 0x5c, 0x22, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5c, 0x22, 0x20, 0x6f,
- 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x69, 0x74,
- 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x65, 0x66, 0x61,
- 0x75, 0x6c, 0x74, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x5c, 0x22, 0x6c, 0x61,
- 0x73, 0x74, 0x5c, 0x22, 0x2e, 0x22, 0x3b, 0x0a, 0x20, 0x20, 0x7d, 0x0a,
- 0x0a, 0x20, 0x20, 0x6d, 0x64, 0x3a, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61,
- 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x7b,
- 0x0a, 0x20, 0x20, 0x20, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x73, 0x74,
- 0x72, 0x69, 0x6e, 0x67, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65,
- 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x20, 0x22, 0x52, 0x46, 0x43,
- 0x37, 0x39, 0x35, 0x30, 0x20, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e,
- 0x20, 0x37, 0x2e, 0x37, 0x2e, 0x39, 0x2e, 0x22, 0x3b, 0x0a, 0x20, 0x20,
- 0x20, 0x20, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f,
- 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x49, 0x6e, 0x20,
- 0x75, 0x73, 0x65, 0x72, 0x20, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x65, 0x64,
- 0x20, 0x6c, 0x65, 0x61, 0x66, 0x2d, 0x6c, 0x69, 0x73, 0x74, 0x2c, 0x20,
- 0x74, 0x68, 0x65, 0x20, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74,
- 0x65, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x75, 0x73,
- 0x65, 0x64, 0x20, 0x69, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x74,
- 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20,
- 0x20, 0x20, 0x20, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x20, 0x69, 0x73,
- 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x70,
- 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x73, 0x20, 0x62, 0x65, 0x66, 0x6f,
- 0x72, 0x65, 0x2f, 0x61, 0x66, 0x74, 0x65, 0x72, 0x20, 0x77, 0x68, 0x69,
- 0x63, 0x68, 0x20, 0x65, 0x78, 0x69, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x20,
- 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x74, 0x68, 0x65,
- 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6e, 0x65, 0x77, 0x20,
- 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x73, 0x68, 0x6f,
- 0x75, 0x6c, 0x64, 0x20, 0x62, 0x65, 0x20, 0x69, 0x6e, 0x73, 0x65, 0x72,
- 0x74, 0x65, 0x64, 0x2e, 0x22, 0x3b, 0x0a, 0x20, 0x20, 0x7d, 0x0a, 0x0a,
- 0x20, 0x20, 0x6d, 0x64, 0x3a, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74,
- 0x69, 0x6f, 0x6e, 0x20, 0x6b, 0x65, 0x79, 0x20, 0x7b, 0x0a, 0x20, 0x20,
- 0x20, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e,
- 0x67, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x66, 0x65, 0x72,
- 0x65, 0x6e, 0x63, 0x65, 0x20, 0x22, 0x52, 0x46, 0x43, 0x37, 0x39, 0x35,
- 0x30, 0x20, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x37, 0x2e,
- 0x38, 0x2e, 0x36, 0x2e, 0x22, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x64,
- 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x49, 0x6e, 0x20, 0x75, 0x73, 0x65,
- 0x72, 0x20, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x65, 0x64, 0x20, 0x6c, 0x69,
- 0x73, 0x74, 0x2c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x74, 0x74, 0x72,
- 0x69, 0x62, 0x75, 0x74, 0x65, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62,
- 0x65, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x69, 0x66, 0x20, 0x74, 0x68,
- 0x65, 0x20, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x0a,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x6e, 0x73, 0x65, 0x72,
- 0x74, 0x20, 0x69, 0x73, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x61, 0x6e,
- 0x64, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x73, 0x20,
- 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x2f, 0x61, 0x66, 0x74, 0x65, 0x72,
- 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x65, 0x78, 0x69, 0x73, 0x74,
- 0x69, 0x6e, 0x67, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65,
- 0x20, 0x74, 0x68, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
- 0x6e, 0x65, 0x77, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65,
- 0x20, 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x62, 0x65, 0x20, 0x69,
- 0x6e, 0x73, 0x65, 0x72, 0x74, 0x65, 0x64, 0x2e, 0x22, 0x3b, 0x0a, 0x20,
- 0x20, 0x7d, 0x0a, 0x0a, 0x20, 0x20, 0x6d, 0x64, 0x3a, 0x61, 0x6e, 0x6e,
- 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x70, 0x65, 0x72,
- 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20,
- 0x74, 0x79, 0x70, 0x65, 0x20, 0x65, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x61,
- 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
- 0x20, 0x65, 0x6e, 0x75, 0x6d, 0x20, 0x6e, 0x6f, 0x6e, 0x65, 0x20, 0x7b,
- 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x65, 0x73,
- 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x20, 0x20, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x54, 0x68, 0x65, 0x20,
- 0x6e, 0x6f, 0x64, 0x65, 0x20, 0x65, 0x78, 0x69, 0x73, 0x74, 0x65, 0x64,
- 0x20, 0x69, 0x6e, 0x20, 0x62, 0x6f, 0x74, 0x68, 0x20, 0x64, 0x61, 0x74,
- 0x61, 0x20, 0x74, 0x72, 0x65, 0x65, 0x73, 0x20, 0x62, 0x75, 0x74, 0x20,
- 0x74, 0x68, 0x65, 0x72, 0x65, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x6e,
- 0x65, 0x73, 0x74, 0x65, 0x64, 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x0a, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x77, 0x69,
- 0x74, 0x68, 0x20, 0x61, 0x6e, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x20, 0x6f,
- 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x20, 0x49, 0x6e,
- 0x20, 0x63, 0x61, 0x73, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x61, 0x20, 0x6c,
- 0x65, 0x61, 0x66, 0x2c, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x69, 0x74,
- 0x73, 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x0a, 0x20, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6c, 0x61,
- 0x67, 0x20, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x2e, 0x22, 0x3b,
- 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20,
- 0x20, 0x20, 0x20, 0x65, 0x6e, 0x75, 0x6d, 0x20, 0x63, 0x72, 0x65, 0x61,
- 0x74, 0x65, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
- 0x20, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e,
- 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
- 0x54, 0x68, 0x65, 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x20, 0x64, 0x69, 0x64,
- 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x65, 0x78, 0x69, 0x73, 0x74, 0x20, 0x69,
- 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20,
- 0x74, 0x72, 0x65, 0x65, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x77, 0x61, 0x73,
- 0x20, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20,
- 0x74, 0x68, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
- 0x20, 0x20, 0x20, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x20, 0x74, 0x72,
- 0x65, 0x65, 0x2e, 0x22, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
- 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x75, 0x6d,
- 0x20, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x20, 0x7b, 0x0a, 0x20, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69,
- 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x22, 0x54, 0x68, 0x65, 0x20, 0x6e, 0x6f, 0x64,
- 0x65, 0x20, 0x65, 0x78, 0x69, 0x73, 0x74, 0x65, 0x64, 0x20, 0x69, 0x6e,
- 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x74,
- 0x72, 0x65, 0x65, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x77, 0x61, 0x73, 0x20,
- 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x74,
- 0x68, 0x65, 0x20, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x0a, 0x20, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x72, 0x65,
- 0x65, 0x2e, 0x22, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d,
- 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x75, 0x6d, 0x20,
- 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x20, 0x7b, 0x0a, 0x20, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69,
- 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x22, 0x54, 0x68, 0x65, 0x20, 0x6e, 0x6f, 0x64,
- 0x65, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x77, 0x61, 0x73, 0x20,
- 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x20, 0x6f, 0x72, 0x20, 0x74,
- 0x68, 0x65, 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x20, 0x77, 0x61, 0x73, 0x20,
- 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x20, 0x66, 0x6f, 0x72, 0x0a, 0x20, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x61,
- 0x76, 0x65, 0x73, 0x2f, 0x61, 0x6e, 0x79, 0x78, 0x6d, 0x6c, 0x2f, 0x61,
- 0x6e, 0x79, 0x64, 0x61, 0x74, 0x61, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x75,
- 0x73, 0x65, 0x72, 0x2d, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x65, 0x64, 0x20,
- 0x6c, 0x69, 0x73, 0x74, 0x73, 0x2f, 0x6c, 0x65, 0x61, 0x66, 0x2d, 0x6c,
- 0x69, 0x73, 0x74, 0x73, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x73, 0x70, 0x65, 0x63, 0x74,
- 0x69, 0x76, 0x65, 0x6c, 0x79, 0x2e, 0x22, 0x3b, 0x0a, 0x20, 0x20, 0x20,
- 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x20,
- 0x20, 0x20, 0x20, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65,
- 0x20, 0x22, 0x52, 0x46, 0x43, 0x36, 0x32, 0x34, 0x31, 0x20, 0x73, 0x65,
- 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x37, 0x2e, 0x32, 0x2e, 0x22, 0x3b,
- 0x0a, 0x20, 0x20, 0x20, 0x20, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70,
- 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
- 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66,
- 0x20, 0x61, 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x61,
- 0x20, 0x64, 0x69, 0x66, 0x66, 0x2e, 0x20, 0x49, 0x66, 0x20, 0x61, 0x20,
- 0x6e, 0x6f, 0x64, 0x65, 0x20, 0x68, 0x61, 0x73, 0x20, 0x6e, 0x6f, 0x20,
- 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x0a, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x74, 0x20, 0x69, 0x73, 0x20,
- 0x69, 0x6e, 0x68, 0x65, 0x72, 0x69, 0x74, 0x65, 0x64, 0x20, 0x66, 0x72,
- 0x6f, 0x6d, 0x20, 0x69, 0x74, 0x73, 0x20, 0x6e, 0x65, 0x61, 0x72, 0x65,
- 0x73, 0x74, 0x20, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x20, 0x77, 0x69,
- 0x74, 0x68, 0x20, 0x61, 0x6e, 0x20, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74,
- 0x69, 0x6f, 0x6e, 0x2e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
- 0x54, 0x6f, 0x70, 0x2d, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x20, 0x6e, 0x6f,
- 0x64, 0x65, 0x73, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x61, 0x6c, 0x77,
- 0x61, 0x79, 0x73, 0x20, 0x68, 0x61, 0x76, 0x65, 0x20, 0x61, 0x6e, 0x20,
- 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x0a, 0x0a,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x55, 0x73, 0x65, 0x72, 0x2d,
- 0x6f, 0x72, 0x64, 0x65, 0x72, 0x65, 0x64, 0x20, 0x6c, 0x69, 0x73, 0x74,
- 0x73, 0x2f, 0x6c, 0x65, 0x61, 0x66, 0x2d, 0x6c, 0x69, 0x73, 0x74, 0x73,
- 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74,
- 0x69, 0x6f, 0x6e, 0x20, 0x27, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x27,
- 0x20, 0x61, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
- 0x27, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x27, 0x20, 0x4d, 0x55,
- 0x53, 0x54, 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x20, 0x68, 0x61, 0x76, 0x65,
- 0x20, 0x74, 0x68, 0x65, 0x20, 0x27, 0x6b, 0x65, 0x79, 0x27, 0x20, 0x6f,
- 0x72, 0x20, 0x27, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x27, 0x20, 0x6d, 0x65,
- 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x20, 0x64, 0x65, 0x66, 0x69, 0x6e,
- 0x65, 0x64, 0x2e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x49,
- 0x74, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x73, 0x20,
- 0x74, 0x68, 0x65, 0x20, 0x73, 0x75, 0x63, 0x63, 0x65, 0x65, 0x64, 0x69,
- 0x6e, 0x67, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x2e,
- 0x20, 0x49, 0x6e, 0x20, 0x63, 0x61, 0x73, 0x65, 0x20, 0x74, 0x68, 0x65,
- 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x6f, 0x66, 0x0a, 0x20, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x6d, 0x65,
- 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x20, 0x69, 0x73, 0x20, 0x65, 0x6d,
- 0x70, 0x74, 0x79, 0x2c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6e, 0x6f, 0x64,
- 0x65, 0x20, 0x77, 0x61, 0x73, 0x20, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65,
- 0x64, 0x2f, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x20, 0x6f, 0x6e, 0x20, 0x74,
- 0x68, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x61,
- 0x73, 0x74, 0x20, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x2e,
- 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x41, 0x6c, 0x6c,
- 0x20, 0x74, 0x68, 0x65, 0x20, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69,
- 0x6f, 0x6e, 0x73, 0x20, 0x6b, 0x65, 0x65, 0x70, 0x20, 0x74, 0x68, 0x65,
- 0x20, 0x6d, 0x65, 0x61, 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x6f, 0x66, 0x20,
- 0x65, 0x64, 0x69, 0x74, 0x2d, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x20,
- 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x0a, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x73,
- 0x69, 0x6d, 0x69, 0x6c, 0x61, 0x72, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x73,
- 0x20, 0x62, 0x75, 0x74, 0x20, 0x73, 0x6f, 0x6d, 0x65, 0x20, 0x61, 0x72,
- 0x65, 0x20, 0x66, 0x75, 0x72, 0x74, 0x68, 0x65, 0x72, 0x20, 0x72, 0x65,
- 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x65, 0x64, 0x2c, 0x20, 0x6d, 0x65,
- 0x61, 0x6e, 0x69, 0x6e, 0x67, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
- 0x20, 0x74, 0x68, 0x65, 0x79, 0x20, 0x61, 0x72, 0x65, 0x20, 0x75, 0x73,
- 0x65, 0x64, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20,
- 0x61, 0x20, 0x73, 0x75, 0x62, 0x73, 0x65, 0x74, 0x20, 0x6f, 0x66, 0x20,
- 0x75, 0x73, 0x65, 0x2d, 0x63, 0x61, 0x73, 0x65, 0x73, 0x2e, 0x22, 0x3b,
- 0x0a, 0x20, 0x20, 0x7d, 0x0a, 0x0a, 0x20, 0x20, 0x6d, 0x64, 0x3a, 0x61,
- 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x72,
- 0x69, 0x67, 0x2d, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x7b,
- 0x0a, 0x20, 0x20, 0x20, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x62, 0x6f,
- 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x64,
- 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x49, 0x6e, 0x66, 0x6f, 0x72, 0x6d,
- 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x62, 0x6f, 0x75, 0x74, 0x20,
- 0x74, 0x68, 0x65, 0x20, 0x70, 0x72, 0x65, 0x76, 0x69, 0x6f, 0x75, 0x73,
- 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x73, 0x74, 0x61,
- 0x74, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6e, 0x6f,
- 0x64, 0x65, 0x2e, 0x22, 0x3b, 0x0a, 0x20, 0x20, 0x7d, 0x0a, 0x0a, 0x20,
- 0x20, 0x6d, 0x64, 0x3a, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69,
- 0x6f, 0x6e, 0x20, 0x6f, 0x72, 0x69, 0x67, 0x2d, 0x76, 0x61, 0x6c, 0x75,
- 0x65, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x74, 0x79, 0x70, 0x65,
- 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3b, 0x0a, 0x20, 0x20, 0x20,
- 0x20, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e,
- 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x50, 0x72, 0x65, 0x76,
- 0x69, 0x6f, 0x75, 0x73, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x6f,
- 0x66, 0x20, 0x61, 0x20, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x20,
- 0x6c, 0x65, 0x61, 0x66, 0x2e, 0x20, 0x41, 0x6c, 0x74, 0x65, 0x72, 0x6e,
- 0x61, 0x74, 0x6c, 0x79, 0x2c, 0x20, 0x69, 0x74, 0x73, 0x20, 0x6d, 0x65,
- 0x61, 0x6e, 0x69, 0x6e, 0x67, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
- 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x61, 0x6d, 0x65, 0x20,
- 0x61, 0x73, 0x20, 0x5c, 0x22, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5c, 0x22,
- 0x20, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x20, 0x62,
- 0x75, 0x74, 0x20, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65,
- 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e,
- 0x61, 0x6c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x61,
- 0x66, 0x2d, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61,
- 0x6e, 0x63, 0x65, 0x20, 0x72, 0x61, 0x74, 0x68, 0x65, 0x72, 0x20, 0x74,
- 0x68, 0x61, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6e, 0x65, 0x77, 0x20,
- 0x6f, 0x6e, 0x65, 0x2e, 0x22, 0x3b, 0x0a, 0x20, 0x20, 0x7d, 0x0a, 0x0a,
- 0x20, 0x20, 0x6d, 0x64, 0x3a, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74,
- 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x72, 0x69, 0x67, 0x2d, 0x6b, 0x65, 0x79,
- 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20,
- 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20,
- 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x0a,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x49, 0x74, 0x73, 0x20, 0x6d,
- 0x65, 0x61, 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68,
- 0x65, 0x20, 0x73, 0x61, 0x6d, 0x65, 0x20, 0x61, 0x73, 0x20, 0x5c, 0x22,
- 0x6b, 0x65, 0x79, 0x5c, 0x22, 0x20, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62,
- 0x75, 0x74, 0x65, 0x20, 0x62, 0x75, 0x74, 0x20, 0x69, 0x64, 0x65, 0x6e,
- 0x74, 0x69, 0x66, 0x69, 0x65, 0x73, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
- 0x20, 0x74, 0x68, 0x65, 0x20, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61,
- 0x6c, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61,
- 0x6e, 0x63, 0x65, 0x20, 0x72, 0x61, 0x74, 0x68, 0x65, 0x72, 0x20, 0x74,
- 0x68, 0x61, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6e, 0x65, 0x77, 0x20,
- 0x6f, 0x6e, 0x65, 0x2e, 0x22, 0x3b, 0x0a, 0x20, 0x20, 0x7d, 0x0a, 0x7d,
- 0x0a, 0x00
-};
diff --git a/models/yang@2021-04-07.h b/models/yang@2021-04-07.h
new file mode 100644
index 0000000..5fbd6d8
--- /dev/null
+++ b/models/yang@2021-04-07.h
@@ -0,0 +1,443 @@
+unsigned char yang_2021_04_07_yang[] = {
+ 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x20, 0x79, 0x61, 0x6e, 0x67, 0x20,
+ 0x7b, 0x0a, 0x20, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63,
+ 0x65, 0x20, 0x22, 0x75, 0x72, 0x6e, 0x3a, 0x69, 0x65, 0x74, 0x66, 0x3a,
+ 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x3a, 0x78, 0x6d, 0x6c, 0x3a, 0x6e,
+ 0x73, 0x3a, 0x79, 0x61, 0x6e, 0x67, 0x3a, 0x31, 0x22, 0x3b, 0x0a, 0x20,
+ 0x20, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x20, 0x79, 0x61, 0x6e, 0x67,
+ 0x3b, 0x0a, 0x0a, 0x20, 0x20, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x20,
+ 0x69, 0x65, 0x74, 0x66, 0x2d, 0x79, 0x61, 0x6e, 0x67, 0x2d, 0x6d, 0x65,
+ 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20,
+ 0x20, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x20, 0x6d, 0x64, 0x3b, 0x0a,
+ 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e,
+ 0x2d, 0x64, 0x61, 0x74, 0x65, 0x20, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30,
+ 0x38, 0x2d, 0x30, 0x35, 0x3b, 0x0a, 0x20, 0x20, 0x7d, 0x0a, 0x0a, 0x20,
+ 0x20, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f,
+ 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, 0x6c, 0x69, 0x62, 0x79, 0x61,
+ 0x6e, 0x67, 0x22, 0x3b, 0x0a, 0x0a, 0x20, 0x20, 0x63, 0x6f, 0x6e, 0x74,
+ 0x61, 0x63, 0x74, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, 0x57, 0x65, 0x62,
+ 0x3a, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a,
+ 0x2f, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d,
+ 0x2f, 0x43, 0x45, 0x53, 0x4e, 0x45, 0x54, 0x2f, 0x6c, 0x69, 0x62, 0x79,
+ 0x61, 0x6e, 0x67, 0x2f, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x41,
+ 0x75, 0x74, 0x68, 0x6f, 0x72, 0x3a, 0x20, 0x52, 0x61, 0x64, 0x65, 0x6b,
+ 0x20, 0x4b, 0x72, 0x65, 0x6a, 0x63, 0x69, 0x20, 0x3c, 0x72, 0x6b, 0x72,
+ 0x65, 0x6a, 0x63, 0x69, 0x40, 0x63, 0x65, 0x73, 0x6e, 0x65, 0x74, 0x2e,
+ 0x63, 0x7a, 0x3e, 0x22, 0x3b, 0x0a, 0x0a, 0x20, 0x20, 0x64, 0x65, 0x73,
+ 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x20, 0x20, 0x20,
+ 0x20, 0x22, 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20,
+ 0x6b, 0x69, 0x6e, 0x64, 0x20, 0x6f, 0x66, 0x20, 0x66, 0x61, 0x6b, 0x65,
+ 0x20, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20,
+ 0x6e, 0x6f, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2c, 0x20, 0x74, 0x79, 0x70,
+ 0x65, 0x64, 0x65, 0x66, 0x73, 0x20, 0x6f, 0x72, 0x20, 0x61, 0x6e, 0x79,
+ 0x74, 0x68, 0x69, 0x6e, 0x67, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65,
+ 0x6c, 0x73, 0x65, 0x2e, 0x20, 0x6c, 0x69, 0x62, 0x79, 0x61, 0x6e, 0x67,
+ 0x20, 0x75, 0x73, 0x65, 0x73, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x6d,
+ 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x69, 0x6d, 0x70,
+ 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x76, 0x61, 0x72, 0x69, 0x6f,
+ 0x75, 0x73, 0x20, 0x59, 0x41, 0x4e, 0x47, 0x20, 0x61, 0x74, 0x74, 0x72,
+ 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x52,
+ 0x46, 0x43, 0x20, 0x36, 0x30, 0x32, 0x30, 0x2e, 0x22, 0x3b, 0x0a, 0x0a,
+ 0x20, 0x20, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x32,
+ 0x30, 0x32, 0x31, 0x2d, 0x30, 0x34, 0x2d, 0x30, 0x37, 0x20, 0x7b, 0x0a,
+ 0x20, 0x20, 0x20, 0x20, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74,
+ 0x69, 0x6f, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x41,
+ 0x64, 0x64, 0x65, 0x64, 0x20, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74,
+ 0x61, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x6b, 0x65, 0x79, 0x2d, 0x6c, 0x65,
+ 0x73, 0x73, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x61, 0x6e, 0x64, 0x20,
+ 0x73, 0x74, 0x61, 0x74, 0x65, 0x20, 0x6c, 0x65, 0x61, 0x66, 0x2d, 0x6c,
+ 0x69, 0x73, 0x74, 0x20, 0x64, 0x69, 0x66, 0x66, 0x2e, 0x22, 0x3b, 0x0a,
+ 0x20, 0x20, 0x7d, 0x0a, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x76, 0x69, 0x73,
+ 0x69, 0x6f, 0x6e, 0x20, 0x32, 0x30, 0x32, 0x30, 0x2d, 0x30, 0x36, 0x2d,
+ 0x31, 0x37, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x64, 0x65, 0x73,
+ 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x22, 0x41, 0x64, 0x64, 0x65, 0x64, 0x20, 0x6d, 0x65,
+ 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x64,
+ 0x69, 0x66, 0x66, 0x2e, 0x22, 0x3b, 0x0a, 0x20, 0x20, 0x7d, 0x0a, 0x0a,
+ 0x20, 0x20, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x32,
+ 0x30, 0x31, 0x37, 0x2d, 0x30, 0x32, 0x2d, 0x32, 0x30, 0x20, 0x7b, 0x0a,
+ 0x20, 0x20, 0x20, 0x20, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74,
+ 0x69, 0x6f, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x41,
+ 0x64, 0x64, 0x65, 0x64, 0x20, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74,
+ 0x61, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x4e, 0x45, 0x54, 0x43, 0x4f, 0x4e,
+ 0x46, 0x27, 0x73, 0x20, 0x65, 0x64, 0x69, 0x74, 0x2d, 0x63, 0x6f, 0x6e,
+ 0x66, 0x69, 0x67, 0x20, 0x6d, 0x61, 0x6e, 0x69, 0x70, 0x75, 0x6c, 0x61,
+ 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x6f, 0x72,
+ 0x64, 0x65, 0x72, 0x65, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x6c, 0x69, 0x73, 0x74, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6c,
+ 0x65, 0x61, 0x66, 0x2d, 0x6c, 0x69, 0x73, 0x74, 0x73, 0x2e, 0x22, 0x3b,
+ 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e,
+ 0x63, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x52, 0x46,
+ 0x43, 0x20, 0x37, 0x39, 0x35, 0x30, 0x3a, 0x20, 0x54, 0x68, 0x65, 0x20,
+ 0x59, 0x41, 0x4e, 0x47, 0x20, 0x31, 0x2e, 0x31, 0x20, 0x44, 0x61, 0x74,
+ 0x61, 0x20, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x69, 0x6e, 0x67, 0x20, 0x4c,
+ 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x22, 0x3b, 0x0a, 0x20, 0x20,
+ 0x7d, 0x0a, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f,
+ 0x6e, 0x20, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x32, 0x2d, 0x31, 0x31,
+ 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x64, 0x65, 0x73, 0x63, 0x72,
+ 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x22, 0x49, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x20, 0x72, 0x65,
+ 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x3b, 0x0a, 0x20, 0x20, 0x20,
+ 0x20, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x0a, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x52, 0x46, 0x43, 0x20, 0x36, 0x30,
+ 0x32, 0x30, 0x3a, 0x20, 0x59, 0x41, 0x4e, 0x47, 0x20, 0x2d, 0x20, 0x41,
+ 0x20, 0x44, 0x61, 0x74, 0x61, 0x20, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x69,
+ 0x6e, 0x67, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x20,
+ 0x66, 0x6f, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74,
+ 0x68, 0x65, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x20, 0x43,
+ 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+ 0x20, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x20, 0x28, 0x4e,
+ 0x45, 0x54, 0x43, 0x4f, 0x4e, 0x46, 0x29, 0x22, 0x3b, 0x0a, 0x20, 0x20,
+ 0x7d, 0x0a, 0x0a, 0x20, 0x20, 0x6d, 0x64, 0x3a, 0x61, 0x6e, 0x6e, 0x6f,
+ 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x6e, 0x73, 0x65, 0x72,
+ 0x74, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x74, 0x79, 0x70, 0x65,
+ 0x20, 0x65, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+ 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x75,
+ 0x6d, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x3b, 0x0a, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x65, 0x6e, 0x75, 0x6d, 0x20, 0x6c, 0x61, 0x73, 0x74,
+ 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x75, 0x6d,
+ 0x20, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x3b, 0x0a, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x65, 0x6e, 0x75, 0x6d, 0x20, 0x61, 0x66, 0x74, 0x65,
+ 0x72, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20,
+ 0x20, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x20, 0x22,
+ 0x52, 0x46, 0x43, 0x37, 0x39, 0x35, 0x30, 0x20, 0x73, 0x65, 0x63, 0x74,
+ 0x69, 0x6f, 0x6e, 0x20, 0x37, 0x2e, 0x38, 0x2e, 0x36, 0x2e, 0x20, 0x61,
+ 0x6e, 0x64, 0x20, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x37,
+ 0x2e, 0x37, 0x2e, 0x39, 0x2e, 0x22, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20,
+ 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x0a,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x49, 0x6e, 0x20, 0x75, 0x73,
+ 0x65, 0x72, 0x20, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x65, 0x64, 0x20, 0x6c,
+ 0x65, 0x61, 0x66, 0x2d, 0x6c, 0x69, 0x73, 0x74, 0x2c, 0x20, 0x74, 0x68,
+ 0x69, 0x73, 0x20, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65,
+ 0x20, 0x63, 0x61, 0x6e, 0x20, 0x62, 0x65, 0x20, 0x75, 0x73, 0x65, 0x64,
+ 0x20, 0x74, 0x6f, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x0a,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x77, 0x68, 0x65, 0x72, 0x65,
+ 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, 0x65, 0x61, 0x66,
+ 0x2d, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x65, 0x6e,
+ 0x74, 0x72, 0x79, 0x20, 0x69, 0x73, 0x20, 0x69, 0x6e, 0x73, 0x65, 0x72,
+ 0x74, 0x65, 0x64, 0x2e, 0x20, 0x49, 0x74, 0x20, 0x63, 0x61, 0x6e, 0x20,
+ 0x62, 0x65, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x64, 0x75, 0x72, 0x69,
+ 0x6e, 0x67, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x68,
+ 0x65, 0x20, 0x4e, 0x45, 0x54, 0x43, 0x4f, 0x4e, 0x46, 0x20, 0x3c, 0x65,
+ 0x64, 0x69, 0x74, 0x2d, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x3e, 0x20,
+ 0x5c, 0x22, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5c, 0x22, 0x20, 0x6f,
+ 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x74, 0x6f,
+ 0x20, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x20, 0x61, 0x20, 0x6e, 0x65,
+ 0x77, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x6f, 0x72, 0x0a, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x61, 0x66, 0x2d, 0x6c, 0x69,
+ 0x73, 0x74, 0x20, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2c, 0x20, 0x6f, 0x72,
+ 0x20, 0x64, 0x75, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x5c, 0x22, 0x6d, 0x65,
+ 0x72, 0x67, 0x65, 0x5c, 0x22, 0x20, 0x6f, 0x72, 0x20, 0x5c, 0x22, 0x72,
+ 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x5c, 0x22, 0x20, 0x6f, 0x70, 0x65,
+ 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x69,
+ 0x6e, 0x73, 0x65, 0x72, 0x74, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x61, 0x20, 0x6e, 0x65, 0x77, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x20,
+ 0x6f, 0x72, 0x20, 0x6c, 0x65, 0x61, 0x66, 0x2d, 0x6c, 0x69, 0x73, 0x74,
+ 0x20, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x20, 0x6f, 0x72, 0x20, 0x6d, 0x6f,
+ 0x76, 0x65, 0x20, 0x61, 0x6e, 0x20, 0x65, 0x78, 0x69, 0x73, 0x74, 0x69,
+ 0x6e, 0x67, 0x20, 0x6f, 0x6e, 0x65, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x49, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x76,
+ 0x61, 0x6c, 0x75, 0x65, 0x20, 0x69, 0x73, 0x20, 0x5c, 0x22, 0x62, 0x65,
+ 0x66, 0x6f, 0x72, 0x65, 0x5c, 0x22, 0x20, 0x6f, 0x72, 0x20, 0x5c, 0x22,
+ 0x61, 0x66, 0x74, 0x65, 0x72, 0x5c, 0x22, 0x2c, 0x20, 0x74, 0x68, 0x65,
+ 0x20, 0x5c, 0x22, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5c, 0x22, 0x2f, 0x5c,
+ 0x22, 0x6b, 0x65, 0x79, 0x5c, 0x22, 0x20, 0x61, 0x74, 0x74, 0x72, 0x69,
+ 0x62, 0x75, 0x74, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x4d, 0x55, 0x53, 0x54, 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x20, 0x62, 0x65,
+ 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x73, 0x70, 0x65,
+ 0x63, 0x69, 0x66, 0x79, 0x20, 0x61, 0x6e, 0x20, 0x65, 0x78, 0x69, 0x73,
+ 0x74, 0x69, 0x6e, 0x67, 0x20, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x20, 0x69,
+ 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x6f,
+ 0x72, 0x20, 0x6c, 0x65, 0x61, 0x66, 0x2d, 0x6c, 0x69, 0x73, 0x74, 0x2e,
+ 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x49, 0x66, 0x20,
+ 0x6e, 0x6f, 0x20, 0x5c, 0x22, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x5c,
+ 0x22, 0x20, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x20,
+ 0x69, 0x73, 0x20, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x20, 0x69,
+ 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x5c, 0x22, 0x63, 0x72, 0x65, 0x61,
+ 0x74, 0x65, 0x5c, 0x22, 0x20, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69,
+ 0x6f, 0x6e, 0x2c, 0x20, 0x69, 0x74, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x73, 0x20, 0x74,
+ 0x6f, 0x20, 0x5c, 0x22, 0x6c, 0x61, 0x73, 0x74, 0x5c, 0x22, 0x2e, 0x22,
+ 0x3b, 0x0a, 0x20, 0x20, 0x7d, 0x0a, 0x0a, 0x20, 0x20, 0x6d, 0x64, 0x3a,
+ 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x76,
+ 0x61, 0x6c, 0x75, 0x65, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x74,
+ 0x79, 0x70, 0x65, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3b, 0x0a,
+ 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63,
+ 0x65, 0x20, 0x22, 0x52, 0x46, 0x43, 0x37, 0x39, 0x35, 0x30, 0x20, 0x73,
+ 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x37, 0x2e, 0x37, 0x2e, 0x39,
+ 0x2e, 0x22, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x64, 0x65, 0x73, 0x63,
+ 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x22, 0x49, 0x6e, 0x20, 0x75, 0x73, 0x65, 0x72, 0x20, 0x6f,
+ 0x72, 0x64, 0x65, 0x72, 0x65, 0x64, 0x20, 0x6c, 0x65, 0x61, 0x66, 0x2d,
+ 0x6c, 0x69, 0x73, 0x74, 0x2c, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x61,
+ 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x20, 0x6d, 0x75, 0x73,
+ 0x74, 0x20, 0x62, 0x65, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x69, 0x66,
+ 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75,
+ 0x74, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x6e,
+ 0x73, 0x65, 0x72, 0x74, 0x20, 0x69, 0x73, 0x20, 0x75, 0x73, 0x65, 0x64,
+ 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69,
+ 0x65, 0x73, 0x20, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x2f, 0x61, 0x66,
+ 0x74, 0x65, 0x72, 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x65, 0x78,
+ 0x69, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61,
+ 0x6e, 0x63, 0x65, 0x20, 0x74, 0x68, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x6e, 0x65, 0x77, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61,
+ 0x6e, 0x63, 0x65, 0x20, 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x62,
+ 0x65, 0x20, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x65, 0x64, 0x2e, 0x22,
+ 0x3b, 0x0a, 0x20, 0x20, 0x7d, 0x0a, 0x0a, 0x20, 0x20, 0x6d, 0x64, 0x3a,
+ 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6b,
+ 0x65, 0x79, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x74, 0x79, 0x70,
+ 0x65, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3b, 0x0a, 0x20, 0x20,
+ 0x20, 0x20, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x20,
+ 0x22, 0x52, 0x46, 0x43, 0x37, 0x39, 0x35, 0x30, 0x20, 0x73, 0x65, 0x63,
+ 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x37, 0x2e, 0x38, 0x2e, 0x36, 0x2e, 0x22,
+ 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69,
+ 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x22, 0x49, 0x6e, 0x20, 0x75, 0x73, 0x65, 0x72, 0x20, 0x6f, 0x72, 0x64,
+ 0x65, 0x72, 0x65, 0x64, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x2c, 0x20, 0x74,
+ 0x68, 0x69, 0x73, 0x20, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74,
+ 0x65, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x75, 0x73,
+ 0x65, 0x64, 0x20, 0x69, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x74,
+ 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x20, 0x69, 0x73,
+ 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x70,
+ 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x73, 0x20, 0x62, 0x65, 0x66, 0x6f,
+ 0x72, 0x65, 0x2f, 0x61, 0x66, 0x74, 0x65, 0x72, 0x20, 0x77, 0x68, 0x69,
+ 0x63, 0x68, 0x20, 0x65, 0x78, 0x69, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x20,
+ 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x74, 0x68, 0x65,
+ 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6e, 0x65, 0x77, 0x20,
+ 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x73, 0x68, 0x6f,
+ 0x75, 0x6c, 0x64, 0x20, 0x62, 0x65, 0x20, 0x69, 0x6e, 0x73, 0x65, 0x72,
+ 0x74, 0x65, 0x64, 0x2e, 0x22, 0x3b, 0x0a, 0x20, 0x20, 0x7d, 0x0a, 0x0a,
+ 0x20, 0x20, 0x6d, 0x64, 0x3a, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74,
+ 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e,
+ 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20,
+ 0x75, 0x6e, 0x69, 0x6f, 0x6e, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x65, 0x6d, 0x70,
+ 0x74, 0x79, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x74, 0x79, 0x70, 0x65, 0x20, 0x75, 0x69, 0x6e, 0x74, 0x33, 0x32, 0x20,
+ 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x20, 0x31, 0x2e, 0x2e, 0x6d,
+ 0x61, 0x78, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20,
+ 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x0a,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x49, 0x6e, 0x20, 0x6b, 0x65,
+ 0x79, 0x2d, 0x6c, 0x65, 0x73, 0x73, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x20,
+ 0x6f, 0x72, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, 0x20, 0x6c, 0x65, 0x61,
+ 0x66, 0x2d, 0x6c, 0x69, 0x73, 0x74, 0x2c, 0x20, 0x74, 0x68, 0x69, 0x73,
+ 0x20, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x20, 0x6d,
+ 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20,
+ 0x69, 0x66, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x68,
+ 0x65, 0x20, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x20,
+ 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x20, 0x69, 0x73, 0x20, 0x75, 0x73,
+ 0x65, 0x64, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69,
+ 0x66, 0x69, 0x65, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x69, 0x6e, 0x73,
+ 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69,
+ 0x6f, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x65,
+ 0x66, 0x6f, 0x72, 0x65, 0x2f, 0x61, 0x66, 0x74, 0x65, 0x72, 0x20, 0x77,
+ 0x68, 0x69, 0x63, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6e, 0x65, 0x77,
+ 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x73, 0x68,
+ 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x62, 0x65, 0x20, 0x69, 0x6e, 0x73, 0x65,
+ 0x72, 0x74, 0x65, 0x64, 0x2e, 0x22, 0x3b, 0x0a, 0x20, 0x20, 0x7d, 0x0a,
+ 0x0a, 0x20, 0x20, 0x6d, 0x64, 0x3a, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61,
+ 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69,
+ 0x6f, 0x6e, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x74, 0x79, 0x70,
+ 0x65, 0x20, 0x65, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f,
+ 0x6e, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e,
+ 0x75, 0x6d, 0x20, 0x6e, 0x6f, 0x6e, 0x65, 0x20, 0x7b, 0x0a, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69,
+ 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x22, 0x54, 0x68, 0x65, 0x20, 0x6e, 0x6f, 0x64,
+ 0x65, 0x20, 0x65, 0x78, 0x69, 0x73, 0x74, 0x65, 0x64, 0x20, 0x69, 0x6e,
+ 0x20, 0x62, 0x6f, 0x74, 0x68, 0x20, 0x64, 0x61, 0x74, 0x61, 0x20, 0x74,
+ 0x72, 0x65, 0x65, 0x73, 0x20, 0x62, 0x75, 0x74, 0x20, 0x74, 0x68, 0x65,
+ 0x72, 0x65, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x6e, 0x65, 0x73, 0x74,
+ 0x65, 0x64, 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20,
+ 0x61, 0x6e, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x20, 0x6f, 0x70, 0x65, 0x72,
+ 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x20, 0x49, 0x6e, 0x20, 0x63, 0x61,
+ 0x73, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x61, 0x20, 0x6c, 0x65, 0x61, 0x66,
+ 0x2c, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x69, 0x74, 0x73, 0x20, 0x64,
+ 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6c, 0x61, 0x67, 0x20, 0x63,
+ 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x2e, 0x22, 0x3b, 0x0a, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x65, 0x6e, 0x75, 0x6d, 0x20, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x20,
+ 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x65,
+ 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x54, 0x68, 0x65,
+ 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x20, 0x64, 0x69, 0x64, 0x20, 0x6e, 0x6f,
+ 0x74, 0x20, 0x65, 0x78, 0x69, 0x73, 0x74, 0x20, 0x69, 0x6e, 0x20, 0x74,
+ 0x68, 0x65, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x74, 0x72, 0x65,
+ 0x65, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x77, 0x61, 0x73, 0x20, 0x63, 0x72,
+ 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65,
+ 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x20, 0x74, 0x72, 0x65, 0x65, 0x2e,
+ 0x22, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x75, 0x6d, 0x20, 0x64, 0x65,
+ 0x6c, 0x65, 0x74, 0x65, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69,
+ 0x6f, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x22, 0x54, 0x68, 0x65, 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x20, 0x65,
+ 0x78, 0x69, 0x73, 0x74, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68,
+ 0x65, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x74, 0x72, 0x65, 0x65,
+ 0x20, 0x61, 0x6e, 0x64, 0x20, 0x77, 0x61, 0x73, 0x20, 0x64, 0x65, 0x6c,
+ 0x65, 0x74, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20,
+ 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x72, 0x65, 0x65, 0x2e, 0x22,
+ 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x75, 0x6d, 0x20, 0x72, 0x65, 0x70,
+ 0x6c, 0x61, 0x63, 0x65, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69,
+ 0x6f, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x22, 0x54, 0x68, 0x65, 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x20, 0x76,
+ 0x61, 0x6c, 0x75, 0x65, 0x20, 0x77, 0x61, 0x73, 0x20, 0x63, 0x68, 0x61,
+ 0x6e, 0x67, 0x65, 0x64, 0x20, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20,
+ 0x6e, 0x6f, 0x64, 0x65, 0x20, 0x77, 0x61, 0x73, 0x20, 0x6d, 0x6f, 0x76,
+ 0x65, 0x64, 0x20, 0x66, 0x6f, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x61, 0x76, 0x65, 0x73,
+ 0x2f, 0x61, 0x6e, 0x79, 0x78, 0x6d, 0x6c, 0x2f, 0x61, 0x6e, 0x79, 0x64,
+ 0x61, 0x74, 0x61, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x75, 0x73, 0x65, 0x72,
+ 0x2d, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x65, 0x64, 0x20, 0x6c, 0x69, 0x73,
+ 0x74, 0x73, 0x2f, 0x6c, 0x65, 0x61, 0x66, 0x2d, 0x6c, 0x69, 0x73, 0x74,
+ 0x73, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x72, 0x65, 0x73, 0x70, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65,
+ 0x6c, 0x79, 0x2e, 0x22, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20,
+ 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x20, 0x22, 0x52,
+ 0x46, 0x43, 0x36, 0x32, 0x34, 0x31, 0x20, 0x73, 0x65, 0x63, 0x74, 0x69,
+ 0x6f, 0x6e, 0x20, 0x37, 0x2e, 0x32, 0x2e, 0x22, 0x3b, 0x0a, 0x20, 0x20,
+ 0x20, 0x20, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f,
+ 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x4f, 0x70, 0x65,
+ 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x61, 0x20,
+ 0x6e, 0x6f, 0x64, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x61, 0x20, 0x64, 0x69,
+ 0x66, 0x66, 0x2e, 0x20, 0x49, 0x66, 0x20, 0x61, 0x20, 0x6e, 0x6f, 0x64,
+ 0x65, 0x20, 0x68, 0x61, 0x73, 0x20, 0x6e, 0x6f, 0x20, 0x6f, 0x70, 0x65,
+ 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x69, 0x74, 0x20, 0x69, 0x73, 0x20, 0x69, 0x6e, 0x68,
+ 0x65, 0x72, 0x69, 0x74, 0x65, 0x64, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20,
+ 0x69, 0x74, 0x73, 0x20, 0x6e, 0x65, 0x61, 0x72, 0x65, 0x73, 0x74, 0x20,
+ 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20,
+ 0x61, 0x6e, 0x20, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+ 0x2e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x54, 0x6f, 0x70,
+ 0x2d, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x73,
+ 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x61, 0x6c, 0x77, 0x61, 0x79, 0x73,
+ 0x20, 0x68, 0x61, 0x76, 0x65, 0x20, 0x61, 0x6e, 0x20, 0x6f, 0x70, 0x65,
+ 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x55, 0x73, 0x65, 0x72, 0x2d, 0x6f, 0x72, 0x64,
+ 0x65, 0x72, 0x65, 0x64, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x73, 0x2f, 0x6c,
+ 0x65, 0x61, 0x66, 0x2d, 0x6c, 0x69, 0x73, 0x74, 0x73, 0x20, 0x77, 0x69,
+ 0x74, 0x68, 0x20, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+ 0x20, 0x27, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x27, 0x20, 0x61, 0x6e,
+ 0x64, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x27, 0x72, 0x65,
+ 0x70, 0x6c, 0x61, 0x63, 0x65, 0x27, 0x20, 0x4d, 0x55, 0x53, 0x54, 0x20,
+ 0x61, 0x6c, 0x73, 0x6f, 0x20, 0x68, 0x61, 0x76, 0x65, 0x20, 0x74, 0x68,
+ 0x65, 0x20, 0x27, 0x6b, 0x65, 0x79, 0x27, 0x2c, 0x20, 0x27, 0x76, 0x61,
+ 0x6c, 0x75, 0x65, 0x27, 0x2c, 0x20, 0x6f, 0x72, 0x20, 0x27, 0x70, 0x6f,
+ 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x27, 0x0a, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x20,
+ 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x2e, 0x20, 0x49, 0x74, 0x20,
+ 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x73, 0x20, 0x74, 0x68,
+ 0x65, 0x20, 0x70, 0x72, 0x65, 0x63, 0x65, 0x64, 0x69, 0x6e, 0x67, 0x20,
+ 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x2e, 0x0a, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x49, 0x6e, 0x20, 0x63, 0x61, 0x73, 0x65,
+ 0x20, 0x74, 0x68, 0x65, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x6f,
+ 0x66, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x6d, 0x65, 0x74, 0x61, 0x64,
+ 0x61, 0x74, 0x61, 0x20, 0x69, 0x73, 0x20, 0x65, 0x6d, 0x70, 0x74, 0x79,
+ 0x2c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x20, 0x77,
+ 0x61, 0x73, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x72,
+ 0x65, 0x61, 0x74, 0x65, 0x64, 0x2f, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x20,
+ 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74,
+ 0x20, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x0a, 0x0a,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x41, 0x6c, 0x6c, 0x20, 0x74,
+ 0x68, 0x65, 0x20, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+ 0x73, 0x20, 0x6b, 0x65, 0x65, 0x70, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6d,
+ 0x65, 0x61, 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x6f, 0x66, 0x20, 0x65, 0x64,
+ 0x69, 0x74, 0x2d, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x20, 0x6f, 0x70,
+ 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x0a, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x73, 0x69, 0x6d,
+ 0x69, 0x6c, 0x61, 0x72, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x20, 0x62,
+ 0x75, 0x74, 0x20, 0x73, 0x6f, 0x6d, 0x65, 0x20, 0x61, 0x72, 0x65, 0x20,
+ 0x66, 0x75, 0x72, 0x74, 0x68, 0x65, 0x72, 0x20, 0x72, 0x65, 0x73, 0x74,
+ 0x72, 0x69, 0x63, 0x74, 0x65, 0x64, 0x2c, 0x20, 0x6d, 0x65, 0x61, 0x6e,
+ 0x69, 0x6e, 0x67, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74,
+ 0x68, 0x65, 0x79, 0x20, 0x61, 0x72, 0x65, 0x20, 0x75, 0x73, 0x65, 0x64,
+ 0x20, 0x66, 0x6f, 0x72, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x61, 0x20,
+ 0x73, 0x75, 0x62, 0x73, 0x65, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x75, 0x73,
+ 0x65, 0x2d, 0x63, 0x61, 0x73, 0x65, 0x73, 0x2e, 0x22, 0x3b, 0x0a, 0x20,
+ 0x20, 0x7d, 0x0a, 0x0a, 0x20, 0x20, 0x6d, 0x64, 0x3a, 0x61, 0x6e, 0x6e,
+ 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x72, 0x69, 0x67,
+ 0x2d, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x7b, 0x0a, 0x20,
+ 0x20, 0x20, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x62, 0x6f, 0x6f, 0x6c,
+ 0x65, 0x61, 0x6e, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x64, 0x65, 0x73,
+ 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x22, 0x49, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74,
+ 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x62, 0x6f, 0x75, 0x74, 0x20, 0x74, 0x68,
+ 0x65, 0x20, 0x70, 0x72, 0x65, 0x76, 0x69, 0x6f, 0x75, 0x73, 0x20, 0x64,
+ 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65,
+ 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6e, 0x6f, 0x64, 0x65,
+ 0x2e, 0x22, 0x3b, 0x0a, 0x20, 0x20, 0x7d, 0x0a, 0x0a, 0x20, 0x20, 0x6d,
+ 0x64, 0x3a, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+ 0x20, 0x6f, 0x72, 0x69, 0x67, 0x2d, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20,
+ 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x73,
+ 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x64,
+ 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x50, 0x72, 0x65, 0x76, 0x69, 0x6f,
+ 0x75, 0x73, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x6f, 0x66, 0x20,
+ 0x61, 0x20, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x20, 0x6c, 0x65,
+ 0x61, 0x66, 0x2e, 0x20, 0x41, 0x6c, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74,
+ 0x69, 0x76, 0x65, 0x6c, 0x79, 0x2c, 0x20, 0x69, 0x74, 0x73, 0x20, 0x6d,
+ 0x65, 0x61, 0x6e, 0x69, 0x6e, 0x67, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x61, 0x6d,
+ 0x65, 0x20, 0x61, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x5c, 0x22, 0x76,
+ 0x61, 0x6c, 0x75, 0x65, 0x5c, 0x22, 0x20, 0x61, 0x74, 0x74, 0x72, 0x69,
+ 0x62, 0x75, 0x74, 0x65, 0x20, 0x62, 0x75, 0x74, 0x20, 0x69, 0x64, 0x65,
+ 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20,
+ 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x0a, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x61, 0x66, 0x2d, 0x6c, 0x69, 0x73,
+ 0x74, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x72,
+ 0x61, 0x74, 0x68, 0x65, 0x72, 0x20, 0x74, 0x68, 0x61, 0x6e, 0x20, 0x74,
+ 0x68, 0x65, 0x20, 0x6e, 0x65, 0x77, 0x20, 0x6f, 0x6e, 0x65, 0x2e, 0x22,
+ 0x3b, 0x0a, 0x20, 0x20, 0x7d, 0x0a, 0x0a, 0x20, 0x20, 0x6d, 0x64, 0x3a,
+ 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f,
+ 0x72, 0x69, 0x67, 0x2d, 0x6b, 0x65, 0x79, 0x20, 0x7b, 0x0a, 0x20, 0x20,
+ 0x20, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e,
+ 0x67, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x64, 0x65, 0x73, 0x63, 0x72,
+ 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x22, 0x49, 0x74, 0x73, 0x20, 0x6d, 0x65, 0x61, 0x6e, 0x69, 0x6e,
+ 0x67, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x61, 0x6d,
+ 0x65, 0x20, 0x61, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x5c, 0x22, 0x6b,
+ 0x65, 0x79, 0x5c, 0x22, 0x20, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75,
+ 0x74, 0x65, 0x20, 0x62, 0x75, 0x74, 0x20, 0x69, 0x64, 0x65, 0x6e, 0x74,
+ 0x69, 0x66, 0x69, 0x65, 0x73, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x74, 0x68, 0x65, 0x20, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61,
+ 0x6c, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61,
+ 0x6e, 0x63, 0x65, 0x20, 0x72, 0x61, 0x74, 0x68, 0x65, 0x72, 0x20, 0x74,
+ 0x68, 0x61, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6e, 0x65, 0x77, 0x20,
+ 0x6f, 0x6e, 0x65, 0x2e, 0x22, 0x3b, 0x0a, 0x20, 0x20, 0x7d, 0x0a, 0x0a,
+ 0x20, 0x20, 0x6d, 0x64, 0x3a, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74,
+ 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x72, 0x69, 0x67, 0x2d, 0x70, 0x6f, 0x73,
+ 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20,
+ 0x74, 0x79, 0x70, 0x65, 0x20, 0x75, 0x6e, 0x69, 0x6f, 0x6e, 0x20, 0x7b,
+ 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x79, 0x70,
+ 0x65, 0x20, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x3b, 0x0a, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x75, 0x69,
+ 0x6e, 0x74, 0x33, 0x32, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x61, 0x6e, 0x67, 0x65,
+ 0x20, 0x31, 0x2e, 0x2e, 0x6d, 0x61, 0x78, 0x3b, 0x0a, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d,
+ 0x0a, 0x20, 0x20, 0x20, 0x20, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70,
+ 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
+ 0x49, 0x74, 0x73, 0x20, 0x6d, 0x65, 0x61, 0x6e, 0x69, 0x6e, 0x67, 0x20,
+ 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x61, 0x6d, 0x65, 0x20,
+ 0x61, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x5c, 0x22, 0x70, 0x6f, 0x73,
+ 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x5c, 0x22, 0x20, 0x61, 0x74, 0x74, 0x72,
+ 0x69, 0x62, 0x75, 0x74, 0x65, 0x20, 0x62, 0x75, 0x74, 0x20, 0x69, 0x64,
+ 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x73, 0x0a, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6f, 0x72, 0x69, 0x67,
+ 0x69, 0x6e, 0x61, 0x6c, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x69, 0x6e,
+ 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x72, 0x61, 0x74, 0x68, 0x65,
+ 0x72, 0x20, 0x74, 0x68, 0x61, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6e,
+ 0x65, 0x77, 0x20, 0x6f, 0x6e, 0x65, 0x2e, 0x22, 0x3b, 0x0a, 0x20, 0x20,
+ 0x7d, 0x0a, 0x7d, 0x0a, 0x00
+};
diff --git a/models/yang@2020-06-17.yang b/models/yang@2021-04-07.yang
similarity index 72%
rename from models/yang@2020-06-17.yang
rename to models/yang@2021-04-07.yang
index 7e596b1..fafa4f2 100644
--- a/models/yang@2020-06-17.yang
+++ b/models/yang@2021-04-07.yang
@@ -19,6 +19,11 @@
else. libyang uses this module to implement various YANG attributes
defined in RFC 6020.";
+ revision 2021-04-07 {
+ description
+ "Added metadata for key-less list and state leaf-list diff.";
+ }
+
revision 2020-06-17 {
description
"Added metadata for diff.";
@@ -49,7 +54,7 @@
}
reference "RFC7950 section 7.8.6. and section 7.7.9.";
description
- "In user ordered leaf-list, the attribute can be used to control
+ "In user ordered leaf-list, this attribute can be used to control
where in the leaf-list the entry is inserted. It can be used during
the NETCONF <edit-config> \"create\" operations to insert a new list or
leaf-list entry, or during \"merge\" or \"replace\" operations to insert
@@ -66,7 +71,7 @@
type string;
reference "RFC7950 section 7.7.9.";
description
- "In user ordered leaf-list, the attribute must be used if the attribute
+ "In user ordered leaf-list, this attribute must be used if the attribute
insert is used and specifies before/after which existing instance the
new instance should be inserted.";
}
@@ -75,11 +80,24 @@
type string;
reference "RFC7950 section 7.8.6.";
description
- "In user ordered list, the attribute must be used if the attribute
+ "In user ordered list, this attribute must be used if the attribute
insert is used and specifies before/after which existing instance the
new instance should be inserted.";
}
+ md:annotation position {
+ type union {
+ type empty;
+ type uint32 {
+ range 1..max;
+ }
+ }
+ description
+ "In key-less list or state leaf-list, this attribute must be used if
+ the attribute insert is used and specifies the instance position
+ before/after which the new instance should be inserted.";
+ }
+
md:annotation operation {
type enumeration {
enum none {
@@ -112,10 +130,10 @@
Top-level nodes must always have an operation.
User-ordered lists/leaf-lists with operation 'create' and
- 'replace' MUST also have the 'key' or 'value' metadata defined.
- It specifies the succeeding instance. In case the value of
- this metadata is empty, the node was created/moved on the
- last position.
+ 'replace' MUST also have the 'key', 'value', or 'position'
+ metadata defined. It specifies the preceding instance.
+ In case the value of this metadata is empty, the node was
+ created/moved on the first position.
All the operations keep the meaning of edit-config operations
with similar names but some are further restricted, meaning
@@ -131,15 +149,27 @@
md:annotation orig-value {
type string;
description
- "Previous value of a changed leaf. Alternatly, its meaning
- is the same as \"value\" attribute but identifies the original
+ "Previous value of a changed leaf. Alternatively, its meaning
+ is the same as the \"value\" attribute but identifies the original
leaf-list instance rather than the new one.";
}
md:annotation orig-key {
type string;
description
- "Its meaning is the same as \"key\" attribute but identifies
+ "Its meaning is the same as the \"key\" attribute but identifies
+ the original list instance rather than the new one.";
+ }
+
+ md:annotation orig-position {
+ type union {
+ type empty;
+ type uint32 {
+ range 1..max;
+ }
+ }
+ description
+ "Its meaning is the same as the \"position\" attribute but identifies
the original list instance rather than the new one.";
}
}
diff --git a/src/context.c b/src/context.c
index 8d074f5..5c240de 100644
--- a/src/context.c
+++ b/src/context.c
@@ -50,7 +50,7 @@
#include "../models/ietf-yang-library@2019-01-04.h"
#include "../models/ietf-yang-metadata@2016-08-05.h"
#include "../models/ietf-yang-types@2013-07-15.h"
-#include "../models/yang@2020-06-17.h"
+#include "../models/yang@2021-04-07.h"
#define IETF_YANG_LIB_REV "2019-01-04"
static struct internal_modules_s {
@@ -61,7 +61,7 @@
LYS_INFORMAT format;
} internal_modules[] = {
{"ietf-yang-metadata", "2016-08-05", (const char *)ietf_yang_metadata_2016_08_05_yang, 0, LYS_IN_YANG},
- {"yang", "2020-06-17", (const char *)yang_2020_06_17_yang, 1, LYS_IN_YANG},
+ {"yang", "2021-04-07", (const char *)yang_2021_04_07_yang, 1, LYS_IN_YANG},
{"ietf-inet-types", "2013-07-15", (const char *)ietf_inet_types_2013_07_15_yang, 0, LYS_IN_YANG},
{"ietf-yang-types", "2013-07-15", (const char *)ietf_yang_types_2013_07_15_yang, 0, LYS_IN_YANG},
/* ietf-datastores and ietf-yang-library must be right here at the end of the list! */
diff --git a/src/diff.c b/src/diff.c
index bdbad69..ee95527 100644
--- a/src/diff.c
+++ b/src/diff.c
@@ -3,7 +3,7 @@
* @author Michal Vasko <mvasko@cesnet.cz>
* @brief diff functions
*
- * Copyright (c) 2020 CESNET, z.s.p.o.
+ * Copyright (c) 2020 - 2021 CESNET, z.s.p.o.
*
* This source code is licensed under BSD 3-Clause License (the "License").
* You may not use this file except in compliance with the License.
@@ -12,15 +12,19 @@
* https://opensource.org/licenses/BSD-3-Clause
*/
#define _POSIX_C_SOURCE 200809L /* strdup */
+#define _GNU_SOURCE /* asprintf */
#include "diff.h"
#include <assert.h>
#include <stddef.h>
+#include <stdint.h>
+#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "common.h"
+#include "compat.h"
#include "context.h"
#include "log.h"
#include "plugins_types.h"
@@ -74,7 +78,8 @@
LY_ERR
lyd_diff_add(const struct lyd_node *node, enum lyd_diff_op op, const char *orig_default, const char *orig_value,
- const char *key, const char *value, const char *orig_key, struct lyd_node **diff)
+ const char *key, const char *value, const char *position, const char *orig_key, const char *orig_position,
+ struct lyd_node **diff)
{
struct lyd_node *dup, *siblings, *match = NULL, *diff_parent = NULL;
const struct lyd_node *parent = NULL;
@@ -87,15 +92,16 @@
/* create on userord needs key/value */
assert((node->schema->nodetype != LYS_LIST) || !(node->schema->flags & LYS_ORDBY_USER) || (op != LYD_DIFF_OP_CREATE) ||
- key);
+ (lysc_is_dup_inst_list(node->schema) && position) || key);
assert((node->schema->nodetype != LYS_LEAFLIST) || !(node->schema->flags & LYS_ORDBY_USER) ||
- (op != LYD_DIFF_OP_CREATE) || value);
+ (op != LYD_DIFF_OP_CREATE) || (lysc_is_dup_inst_list(node->schema) && position) || value);
/* move on userord needs both key and orig-key/value and orig-value */
assert((node->schema->nodetype != LYS_LIST) || !(node->schema->flags & LYS_ORDBY_USER) || (op != LYD_DIFF_OP_REPLACE) ||
- (key && orig_key));
+ (lysc_is_dup_inst_list(node->schema) && position && orig_position) || (key && orig_key));
assert((node->schema->nodetype != LYS_LEAFLIST) || !(node->schema->flags & LYS_ORDBY_USER) ||
- (op != LYD_DIFF_OP_REPLACE) || (value && orig_value));
+ (op != LYD_DIFF_OP_REPLACE) || (lysc_is_dup_inst_list(node->schema) && position && orig_position) ||
+ (value && orig_value));
/* find the first existing parent */
siblings = *diff;
@@ -179,11 +185,21 @@
LY_CHECK_RET(lyd_new_meta(LYD_CTX(node), dup, yang_mod, "value", value, 0, NULL));
}
+ /* position */
+ if (position) {
+ LY_CHECK_RET(lyd_new_meta(LYD_CTX(node), dup, yang_mod, "position", position, 0, NULL));
+ }
+
/* orig-key */
if (orig_key) {
LY_CHECK_RET(lyd_new_meta(LYD_CTX(node), dup, yang_mod, "orig-key", orig_key, 0, NULL));
}
+ /* orig-position */
+ if (orig_position) {
+ LY_CHECK_RET(lyd_new_meta(LYD_CTX(node), dup, yang_mod, "orig-position", orig_position, 0, NULL));
+ }
+
return LY_SUCCESS;
}
@@ -199,7 +215,8 @@
lyd_diff_userord_get(const struct lyd_node *first, const struct lysc_node *schema, struct lyd_diff_userord **userord)
{
struct lyd_diff_userord *item;
- const struct lyd_node *iter, **node;
+ struct lyd_node *iter;
+ const struct lyd_node **node;
LY_ARRAY_COUNT_TYPE u;
LY_ARRAY_FOR(*userord, u) {
@@ -217,16 +234,9 @@
/* store all the instance pointers in the current order */
if (first) {
- if (first->parent) {
- iter = first->parent->child;
- } else {
- for (iter = first; iter->prev->next; iter = iter->prev) {}
- }
- for ( ; iter; iter = iter->next) {
- if (iter->schema == first->schema) {
- LY_ARRAY_NEW_RET(schema->module->ctx, item->inst, node, NULL);
- *node = iter;
- }
+ LYD_LIST_FOR_INST(lyd_first_sibling(first), first->schema, iter) {
+ LY_ARRAY_NEW_RET(schema->module->ctx, item->inst, node, NULL);
+ *node = iter;
}
}
@@ -247,6 +257,8 @@
* @param[out] orig_value Original value metadata
* @param[out] key Key metadata.
* @param[out] orig_key Original key metadata.
+ * @param[out] position Position metadata.
+ * @param[out] orig_position Original position metadata.
* @return LY_SUCCESS on success,
* @return LY_ENOT if there is no change to be added into diff,
* @return LY_ERR value on other errors.
@@ -254,10 +266,11 @@
static LY_ERR
lyd_diff_userord_attrs(const struct lyd_node *first, const struct lyd_node *second, uint16_t options,
struct lyd_diff_userord **userord, enum lyd_diff_op *op, const char **orig_default, char **value,
- char **orig_value, char **key, char **orig_key)
+ char **orig_value, char **key, char **orig_key, char **position, char **orig_position)
{
const struct lysc_node *schema;
- size_t buflen, bufused, first_pos, second_pos;
+ size_t buflen, bufused;
+ uint32_t first_pos, second_pos;
struct lyd_diff_userord *userord_item;
assert(first || second);
@@ -267,6 +280,8 @@
*orig_value = NULL;
*key = NULL;
*orig_key = NULL;
+ *position = NULL;
+ *orig_position = NULL;
schema = first ? first->schema : second->schema;
assert(lysc_is_userordered(schema));
@@ -275,12 +290,9 @@
userord_item = lyd_diff_userord_get(first, schema, userord);
LY_CHECK_RET(!userord_item, LY_EMEM);
- /* prepare position of the next instance */
- second_pos = userord_item->pos++;
-
/* find user-ordered first position */
if (first) {
- for (first_pos = second_pos; first_pos < LY_ARRAY_COUNT(userord_item->inst); ++first_pos) {
+ for (first_pos = 0; first_pos < LY_ARRAY_COUNT(userord_item->inst); ++first_pos) {
if (userord_item->inst[first_pos] == first) {
break;
}
@@ -290,13 +302,15 @@
first_pos = 0;
}
+ /* prepare position of the next instance */
+ second_pos = userord_item->pos++;
+
/* learn operation first */
if (!second) {
*op = LYD_DIFF_OP_DELETE;
} else if (!first) {
*op = LYD_DIFF_OP_CREATE;
} else {
- assert(schema->nodetype & (LYS_LIST | LYS_LEAFLIST));
if (lyd_compare_single(second, userord_item->inst[second_pos], 0)) {
/* in first, there is a different instance on the second position, we are going to move 'first' node */
*op = LYD_DIFF_OP_REPLACE;
@@ -323,7 +337,8 @@
}
/* value */
- if ((schema->nodetype == LYS_LEAFLIST) && ((*op == LYD_DIFF_OP_REPLACE) || (*op == LYD_DIFF_OP_CREATE))) {
+ if ((schema->nodetype == LYS_LEAFLIST) && !lysc_is_dup_inst_list(schema) &&
+ ((*op == LYD_DIFF_OP_REPLACE) || (*op == LYD_DIFF_OP_CREATE))) {
if (second_pos) {
*value = strdup(LYD_CANON_VALUE(userord_item->inst[second_pos - 1]));
LY_CHECK_ERR_RET(!*value, LOGMEM(schema->module->ctx), LY_EMEM);
@@ -334,7 +349,8 @@
}
/* orig-value */
- if ((schema->nodetype == LYS_LEAFLIST) && ((*op == LYD_DIFF_OP_REPLACE) || (*op == LYD_DIFF_OP_DELETE))) {
+ if ((schema->nodetype == LYS_LEAFLIST) && !lysc_is_dup_inst_list(schema) &&
+ ((*op == LYD_DIFF_OP_REPLACE) || (*op == LYD_DIFF_OP_DELETE))) {
if (first_pos) {
*orig_value = strdup(LYD_CANON_VALUE(userord_item->inst[first_pos - 1]));
LY_CHECK_ERR_RET(!*orig_value, LOGMEM(schema->module->ctx), LY_EMEM);
@@ -345,7 +361,8 @@
}
/* key */
- if ((schema->nodetype == LYS_LIST) && ((*op == LYD_DIFF_OP_REPLACE) || (*op == LYD_DIFF_OP_CREATE))) {
+ if ((schema->nodetype == LYS_LIST) && !lysc_is_dup_inst_list(schema) &&
+ ((*op == LYD_DIFF_OP_REPLACE) || (*op == LYD_DIFF_OP_CREATE))) {
if (second_pos) {
buflen = bufused = 0;
LY_CHECK_RET(lyd_path_list_predicate(userord_item->inst[second_pos - 1], key, &buflen, &bufused, 0));
@@ -356,7 +373,8 @@
}
/* orig-key */
- if ((schema->nodetype == LYS_LIST) && ((*op == LYD_DIFF_OP_REPLACE) || (*op == LYD_DIFF_OP_DELETE))) {
+ if ((schema->nodetype == LYS_LIST) && !lysc_is_dup_inst_list(schema) &&
+ ((*op == LYD_DIFF_OP_REPLACE) || (*op == LYD_DIFF_OP_DELETE))) {
if (first_pos) {
buflen = bufused = 0;
LY_CHECK_RET(lyd_path_list_predicate(userord_item->inst[first_pos - 1], orig_key, &buflen, &bufused, 0));
@@ -366,6 +384,32 @@
}
}
+ /* position */
+ if (lysc_is_dup_inst_list(schema) && ((*op == LYD_DIFF_OP_REPLACE) || (*op == LYD_DIFF_OP_CREATE))) {
+ if (second_pos) {
+ if (asprintf(position, "%" PRIu32, second_pos) == -1) {
+ LOGMEM(schema->module->ctx);
+ return LY_EMEM;
+ }
+ } else {
+ *position = strdup("");
+ LY_CHECK_ERR_RET(!*position, LOGMEM(schema->module->ctx), LY_EMEM);
+ }
+ }
+
+ /* orig-position */
+ if (lysc_is_dup_inst_list(schema) && ((*op == LYD_DIFF_OP_REPLACE) || (*op == LYD_DIFF_OP_DELETE))) {
+ if (first_pos) {
+ if (asprintf(orig_position, "%" PRIu32, first_pos) == -1) {
+ LOGMEM(schema->module->ctx);
+ return LY_EMEM;
+ }
+ } else {
+ *orig_position = strdup("");
+ LY_CHECK_ERR_RET(!*orig_position, LOGMEM(schema->module->ctx), LY_EMEM);
+ }
+ }
+
/*
* update our instances - apply the change
*/
@@ -494,6 +538,101 @@
}
/**
+ * @brief Find an entry in duplicate instance cache for an instance. Create it if it does not exist.
+ *
+ * @param[in] first_inst Instance of the cache entry.
+ * @param[in,out] dup_inst_cache Duplicate instance cache.
+ * @return Instance cache entry.
+ */
+static struct lyd_diff_dup_inst *
+lyd_diff_dup_inst_get(const struct lyd_node *first_inst, struct lyd_diff_dup_inst **dup_inst_cache)
+{
+ struct lyd_diff_dup_inst *item;
+ LY_ARRAY_COUNT_TYPE u;
+
+ LY_ARRAY_FOR(*dup_inst_cache, u) {
+ if ((*dup_inst_cache)[u].inst_set->dnodes[0] == first_inst) {
+ return &(*dup_inst_cache)[u];
+ }
+ }
+
+ /* it was not added yet, add it now */
+ LY_ARRAY_NEW_RET(LYD_CTX(first_inst), *dup_inst_cache, item, NULL);
+
+ return item;
+}
+
+/**
+ * @brief Free duplicate instance cache.
+ *
+ * @param[in] dup_inst Duplicate instance cache to free.
+ */
+static void
+lyd_diff_dup_inst_free(struct lyd_diff_dup_inst *dup_inst)
+{
+ LY_ARRAY_COUNT_TYPE u;
+
+ LY_ARRAY_FOR(dup_inst, u) {
+ ly_set_free(dup_inst[u].inst_set, NULL);
+ }
+ LY_ARRAY_FREE(dup_inst);
+}
+
+/**
+ * @brief Find a matching instance of a node in a data tree.
+ *
+ * @param[in] siblings Siblings to search in.
+ * @param[in] target Target node to search for.
+ * @param[in] defaults Whether to consider (or ignore) default values.
+ * @param[in,out] dup_inst_cache Duplicate instance cache.
+ * @param[out] match Found match, NULL if no matching node found.
+ * @return LY_ERR value.
+ */
+static LY_ERR
+lyd_diff_find_match(const struct lyd_node *siblings, const struct lyd_node *target, ly_bool defaults,
+ struct lyd_diff_dup_inst **dup_inst_cache, struct lyd_node **match)
+{
+ struct lyd_diff_dup_inst *dup_inst;
+
+ if (target->schema->nodetype & (LYS_LIST | LYS_LEAFLIST)) {
+ /* try to find the exact instance */
+ lyd_find_sibling_first(siblings, target, match);
+ } else {
+ /* try to simply find the node, there cannot be more instances */
+ lyd_find_sibling_val(siblings, target->schema, NULL, 0, match);
+ }
+
+ if (*match && lysc_is_dup_inst_list(target->schema)) {
+ /* there can be more exact same instances and we must make sure we do not match a single node more times */
+ dup_inst = lyd_diff_dup_inst_get(*match, dup_inst_cache);
+ LY_CHECK_ERR_RET(!dup_inst, LOGMEM(LYD_CTX(target)), LY_EMEM);
+
+ if (!dup_inst->used) {
+ /* we did not cache these instances yet, do so */
+ lyd_find_sibling_dup_inst_set(siblings, target, &dup_inst->inst_set);
+ assert(dup_inst->inst_set->count && (dup_inst->inst_set->dnodes[0] == *match));
+ }
+
+ if (dup_inst->used == dup_inst->inst_set->count) {
+ /* we have used all the instances */
+ *match = NULL;
+ } else {
+ assert(dup_inst->used < dup_inst->inst_set->count);
+
+ /* use another instance */
+ *match = dup_inst->inst_set->dnodes[dup_inst->used];
+ ++dup_inst->used;
+ }
+ }
+
+ if (*match && ((*match)->flags & LYD_DEFAULT) && !defaults) {
+ /* ignore default nodes */
+ *match = NULL;
+ }
+ return LY_SUCCESS;
+}
+
+/**
* @brief Perform diff for all siblings at certain depth, recursively.
*
* For user-ordered lists/leaf-lists a specific structure is used for storing
@@ -542,10 +681,11 @@
const struct lyd_node *iter_first, *iter_second;
struct lyd_node *match_second, *match_first;
struct lyd_diff_userord *userord = NULL;
+ struct lyd_diff_dup_inst *dup_inst_first = NULL, *dup_inst_second = NULL;
LY_ARRAY_COUNT_TYPE u;
enum lyd_diff_op op;
const char *orig_default;
- char *orig_value, *key, *value, *orig_key;
+ char *orig_value, *key, *value, *position, *orig_key, *orig_position;
/* compare first tree to the second tree - delete, replace, none */
LY_LIST_FOR(first, iter_first) {
@@ -555,38 +695,29 @@
continue;
}
- if (iter_first->schema->nodetype & (LYS_LIST | LYS_LEAFLIST)) {
- /* try to find the exact instance */
- lyd_find_sibling_first(second, iter_first, &match_second);
- } else {
- /* try to simply find the node, there cannot be more instances */
- lyd_find_sibling_val(second, iter_first->schema, NULL, 0, &match_second);
- }
-
- if (match_second && (match_second->flags & LYD_DEFAULT) && !(options & LYD_DIFF_DEFAULTS)) {
- /* ignore default nodes */
- match_second = NULL;
- }
+ /* find a match in the second tree */
+ LY_CHECK_GOTO(ret = lyd_diff_find_match(second, iter_first, options & LYD_DIFF_DEFAULTS, &dup_inst_second,
+ &match_second), cleanup);
if (lysc_is_userordered(iter_first->schema)) {
- if (match_second) {
- /* we are handling only user-ordered node delete now */
- continue;
+ /* we are handling only user-ordered node delete now */
+ if (!match_second) {
+ /* get all the attributes */
+ LY_CHECK_GOTO(ret = lyd_diff_userord_attrs(iter_first, match_second, options, &userord, &op, &orig_default,
+ &value, &orig_value, &key, &orig_key, &position, &orig_position), cleanup);
+
+ /* there must be changes, it is deleted */
+ assert(op == LYD_DIFF_OP_DELETE);
+ ret = lyd_diff_add(iter_first, op, orig_default, orig_value, key, value, position, orig_key, orig_position, diff);
+
+ free(orig_value);
+ free(key);
+ free(value);
+ free(position);
+ free(orig_key);
+ free(orig_position);
+ LY_CHECK_GOTO(ret, cleanup);
}
-
- /* get all the attributes */
- LY_CHECK_GOTO(lyd_diff_userord_attrs(iter_first, match_second, options, &userord, &op, &orig_default,
- &value, &orig_value, &key, &orig_key), cleanup);
-
- /* there must be changes, it is deleted */
- assert(op == LYD_DIFF_OP_DELETE);
- ret = lyd_diff_add(iter_first, op, orig_default, orig_value, key, value, orig_key, diff);
-
- free(orig_value);
- free(key);
- free(value);
- free(orig_key);
- LY_CHECK_GOTO(ret, cleanup);
} else {
/* get all the attributes */
ret = lyd_diff_attrs(iter_first, match_second, options, &op, &orig_default, &orig_value);
@@ -594,10 +725,10 @@
/* add into diff if there are any changes */
if (!ret) {
if (op == LYD_DIFF_OP_DELETE) {
- ret = lyd_diff_add(iter_first, op, orig_default, orig_value, NULL, NULL, NULL, diff);
+ ret = lyd_diff_add(iter_first, op, orig_default, orig_value, NULL, NULL, NULL, NULL, NULL, diff);
} else {
assert(match_second);
- ret = lyd_diff_add(match_second, op, orig_default, orig_value, NULL, NULL, NULL, diff);
+ ret = lyd_diff_add(match_second, op, orig_default, orig_value, NULL, NULL, NULL, NULL, NULL, diff);
}
free(orig_value);
@@ -611,8 +742,8 @@
/* check descendants, if any, recursively */
if (match_second) {
- LY_CHECK_GOTO(lyd_diff_siblings_r(lyd_child_no_keys(iter_first), lyd_child_no_keys(match_second), options,
- 0, diff), cleanup);
+ LY_CHECK_GOTO(ret = lyd_diff_siblings_r(lyd_child_no_keys(iter_first), lyd_child_no_keys(match_second),
+ options, 0, diff), cleanup);
}
if (nosiblings) {
@@ -633,30 +764,26 @@
continue;
}
- if (iter_second->schema->nodetype & (LYS_LIST | LYS_LEAFLIST)) {
- lyd_find_sibling_first(first, iter_second, &match_first);
- } else {
- lyd_find_sibling_val(first, iter_second->schema, NULL, 0, &match_first);
- }
-
- if (match_first && (match_first->flags & LYD_DEFAULT) && !(options & LYD_DIFF_DEFAULTS)) {
- /* ignore default nodes */
- match_first = NULL;
- }
+ /* find a match in the first tree */
+ LY_CHECK_GOTO(ret = lyd_diff_find_match(first, iter_second, options & LYD_DIFF_DEFAULTS, &dup_inst_first,
+ &match_first), cleanup);
if (lysc_is_userordered(iter_second->schema)) {
/* get all the attributes */
ret = lyd_diff_userord_attrs(match_first, iter_second, options, &userord, &op, &orig_default,
- &value, &orig_value, &key, &orig_key);
+ &value, &orig_value, &key, &orig_key, &position, &orig_position);
/* add into diff if there are any changes */
if (!ret) {
- ret = lyd_diff_add(iter_second, op, orig_default, orig_value, key, value, orig_key, diff);
+ ret = lyd_diff_add(iter_second, op, orig_default, orig_value, key, value, position, orig_key,
+ orig_position, diff);
free(orig_value);
free(key);
free(value);
+ free(position);
free(orig_key);
+ free(orig_position);
LY_CHECK_GOTO(ret, cleanup);
} else if (ret == LY_ENOT) {
ret = LY_SUCCESS;
@@ -665,11 +792,11 @@
}
} else if (!match_first) {
/* get all the attributes */
- LY_CHECK_GOTO(lyd_diff_attrs(match_first, iter_second, options, &op, &orig_default, &orig_value), cleanup);
+ LY_CHECK_GOTO(ret = lyd_diff_attrs(match_first, iter_second, options, &op, &orig_default, &orig_value), cleanup);
/* there must be changes, it is created */
assert(op == LYD_DIFF_OP_CREATE);
- ret = lyd_diff_add(iter_second, op, orig_default, orig_value, NULL, NULL, NULL, diff);
+ ret = lyd_diff_add(iter_second, op, orig_default, orig_value, NULL, NULL, NULL, NULL, NULL, diff);
free(orig_value);
LY_CHECK_GOTO(ret, cleanup);
@@ -681,6 +808,8 @@
}
cleanup:
+ lyd_diff_dup_inst_free(dup_inst_first);
+ lyd_diff_dup_inst_free(dup_inst_second);
LY_ARRAY_FOR(userord, u) {
LY_ARRAY_FREE(userord[u].inst);
}
@@ -726,25 +855,6 @@
}
/**
- * @brief Find a matching node in data tree for a diff node.
- *
- * @param[in] first_node First sibling in the data tree.
- * @param[in] diff_node Diff node to match.
- * @param[out] match_p Matching node, NULL if no found.
- */
-static void
-lyd_diff_find_node(const struct lyd_node *first_node, const struct lyd_node *diff_node, struct lyd_node **match_p)
-{
- if (diff_node->schema->nodetype & (LYS_LIST | LYS_LEAFLIST)) {
- /* try to find the exact instance */
- lyd_find_sibling_first(first_node, diff_node, match_p);
- } else {
- /* try to simply find the node, there cannot be more instances */
- lyd_find_sibling_val(first_node, diff_node->schema, NULL, 0, match_p);
- }
-}
-
-/**
* @brief Learn operation of a diff node.
*
* @param[in] diff_node Diff node.
@@ -785,16 +895,18 @@
* @param[in,out] first_node First sibling of the data tree.
* @param[in] parent_node Data tree sibling parent node.
* @param[in] new_node Node to insert.
- * @param[in] keys_or_value Optional predicate of relative (leaf-)list instance. If not set, the user-ordered
- * instance will be inserted at the first position.
+ * @param[in] userord_anchor Optional anchor (key, value, or position) of relative (leaf-)list instance. If not set,
+ * the user-ordered instance will be inserted at the first position.
* @return err_info, NULL on success.
*/
static LY_ERR
lyd_diff_insert(struct lyd_node **first_node, struct lyd_node *parent_node, struct lyd_node *new_node,
- const char *key_or_value)
+ const char *userord_anchor)
{
LY_ERR ret;
struct lyd_node *anchor;
+ uint32_t pos, anchor_pos;
+ int found;
assert(new_node);
@@ -806,7 +918,7 @@
}
/* simply insert into parent, no other children */
- if (key_or_value) {
+ if (userord_anchor) {
LOGERR(LYD_CTX(new_node), LY_EINVAL, "Node \"%s\" instance to insert next to not found.",
new_node->schema->name);
return LY_EINVAL;
@@ -821,15 +933,35 @@
return lyd_insert_sibling(*first_node, new_node, first_node);
}
- if (key_or_value) {
+ if (userord_anchor) {
/* find the anchor sibling */
- ret = lyd_find_sibling_val(*first_node, new_node->schema, key_or_value, 0, &anchor);
- if (ret == LY_ENOTFOUND) {
- LOGERR(LYD_CTX(new_node), LY_EINVAL, "Node \"%s\" instance to insert next to not found.",
- new_node->schema->name);
- return LY_EINVAL;
- } else if (ret) {
- return ret;
+ if (lysc_is_dup_inst_list(new_node->schema)) {
+ anchor_pos = atoi(userord_anchor);
+ LY_CHECK_ERR_RET(!anchor_pos, LOGINT(LYD_CTX(new_node)), LY_EINT);
+
+ found = 0;
+ pos = 1;
+ LYD_LIST_FOR_INST(*first_node, new_node->schema, anchor) {
+ if (pos == anchor_pos) {
+ found = 1;
+ break;
+ }
+ ++pos;
+ }
+ if (!found) {
+ LOGERR(LYD_CTX(new_node), LY_EINVAL, "Node \"%s\" instance to insert next to not found.",
+ new_node->schema->name);
+ return LY_EINVAL;
+ }
+ } else {
+ ret = lyd_find_sibling_val(*first_node, new_node->schema, userord_anchor, 0, &anchor);
+ if (ret == LY_ENOTFOUND) {
+ LOGERR(LYD_CTX(new_node), LY_EINVAL, "Node \"%s\" instance to insert next to not found.",
+ new_node->schema->name);
+ return LY_EINVAL;
+ } else if (ret) {
+ return ret;
+ }
}
/* insert after */
@@ -867,17 +999,19 @@
* @param[in] diff_node Current diff node.
* @param[in] diff_cb Optional diff callback.
* @param[in] cb_data User data for @p diff_cb.
+ * @param[in,out] dup_inst Duplicate instance cache for all @p diff_node siblings.
* @return LY_ERR value.
*/
static LY_ERR
lyd_diff_apply_r(struct lyd_node **first_node, struct lyd_node *parent_node, const struct lyd_node *diff_node,
- lyd_diff_cb diff_cb, void *cb_data)
+ lyd_diff_cb diff_cb, void *cb_data, struct lyd_diff_dup_inst **dup_inst)
{
LY_ERR ret;
struct lyd_node *match, *diff_child;
- const char *str_val;
+ const char *str_val, *meta_str;
enum lyd_diff_op op;
struct lyd_meta *meta;
+ struct lyd_diff_dup_inst *child_dup_inst = NULL;
const struct ly_ctx *ctx = LYD_CTX(diff_node);
/* read all the valid attributes */
@@ -887,16 +1021,23 @@
if (lysc_is_userordered(diff_node->schema) && ((op == LYD_DIFF_OP_CREATE) || (op == LYD_DIFF_OP_REPLACE))) {
if (op == LYD_DIFF_OP_REPLACE) {
/* find the node (we must have some siblings because the node was only moved) */
- lyd_diff_find_node(*first_node, diff_node, &match);
- LY_CHECK_ERR_RET(!match, LOGINT(LYD_CTX(diff_node)), LY_EINT);
+ LY_CHECK_RET(lyd_diff_find_match(*first_node, diff_node, 1, dup_inst, &match));
+ LY_CHECK_ERR_RET(!match, LOGINT(ctx), LY_EINT);
} else {
/* duplicate the node */
LY_CHECK_RET(lyd_dup_single(diff_node, NULL, LYD_DUP_NO_META, &match));
}
- /* get "key" or "value" metadata string value */
- meta = lyd_find_meta(diff_node->meta, NULL, diff_node->schema->nodetype == LYS_LIST ? "yang:key" : "yang:value");
- LY_CHECK_ERR_RET(!meta, LOGINT(LYD_CTX(diff_node)), LY_EINT);
+ /* get "key", "value", or "position" metadata string value */
+ if (lysc_is_dup_inst_list(diff_node->schema)) {
+ meta_str = "yang:position";
+ } else if (diff_node->schema->nodetype == LYS_LIST) {
+ meta_str = "yang:key";
+ } else {
+ meta_str = "yang:value";
+ }
+ meta = lyd_find_meta(diff_node->meta, NULL, meta_str);
+ LY_CHECK_ERR_RET(!meta, LOGINT(ctx), LY_EINT);
str_val = meta->value.canonical;
/* insert/move the node */
@@ -919,8 +1060,8 @@
switch (op) {
case LYD_DIFF_OP_NONE:
/* find the node */
- lyd_diff_find_node(*first_node, diff_node, &match);
- LY_CHECK_ERR_RET(!match, LOGINT(LYD_CTX(diff_node)), LY_EINT);
+ LY_CHECK_RET(lyd_diff_find_match(*first_node, diff_node, 1, dup_inst, &match));
+ LY_CHECK_ERR_RET(!match, LOGINT(ctx), LY_EINT);
if (match->schema->nodetype & LYD_NODE_TERM) {
/* special case of only dflt flag change */
@@ -955,8 +1096,8 @@
break;
case LYD_DIFF_OP_DELETE:
/* find the node */
- lyd_diff_find_node(*first_node, diff_node, &match);
- LY_CHECK_ERR_RET(!match, LOGINT(LYD_CTX(diff_node)), LY_EINT);
+ LY_CHECK_RET(lyd_diff_find_match(*first_node, diff_node, 1, dup_inst, &match));
+ LY_CHECK_ERR_RET(!match, LOGINT(ctx), LY_EINT);
/* remove it */
if ((match == *first_node) && !match->parent) {
@@ -972,8 +1113,8 @@
LY_CHECK_ERR_RET(!(diff_node->schema->nodetype & (LYS_LEAF | LYS_ANYDATA)), LOGINT(ctx), LY_EINT);
/* find the node */
- lyd_diff_find_node(*first_node, diff_node, &match);
- LY_CHECK_ERR_RET(!match, LOGINT(LYD_CTX(diff_node)), LY_EINT);
+ LY_CHECK_RET(lyd_diff_find_match(*first_node, diff_node, 1, dup_inst, &match));
+ LY_CHECK_ERR_RET(!match, LOGINT(ctx), LY_EINT);
/* update the value */
if (diff_node->schema->nodetype == LYS_LEAF) {
@@ -983,8 +1124,7 @@
}
} else {
struct lyd_node_any *any = (struct lyd_node_any *)diff_node;
- ret = lyd_any_copy_value(match, &any->value, any->value_type);
- LY_CHECK_RET(ret);
+ LY_CHECK_RET(lyd_any_copy_value(match, &any->value, any->value_type));
}
/* with flags */
@@ -1001,11 +1141,16 @@
}
/* apply diff recursively */
+ ret = LY_SUCCESS;
LY_LIST_FOR(lyd_child_no_keys(diff_node), diff_child) {
- LY_CHECK_RET(lyd_diff_apply_r(lyd_node_child_p(match), match, diff_child, diff_cb, cb_data));
+ ret = lyd_diff_apply_r(lyd_node_child_p(match), match, diff_child, diff_cb, cb_data, &child_dup_inst);
+ if (ret) {
+ break;
+ }
}
- return LY_SUCCESS;
+ lyd_diff_dup_inst_free(child_dup_inst);
+ return ret;
}
API LY_ERR
@@ -1013,6 +1158,8 @@
lyd_diff_cb diff_cb, void *cb_data)
{
const struct lyd_node *root;
+ struct lyd_diff_dup_inst *dup_inst = NULL;
+ LY_ERR ret = LY_SUCCESS;
LY_LIST_FOR(diff, root) {
if (mod && (lyd_owner_module(root) != mod)) {
@@ -1021,10 +1168,14 @@
}
/* apply relevant nodes from the diff datatree */
- LY_CHECK_RET(lyd_diff_apply_r(data, NULL, root, diff_cb, cb_data));
+ ret = lyd_diff_apply_r(data, NULL, root, diff_cb, cb_data, &dup_inst);
+ if (ret) {
+ break;
+ }
}
- return LY_SUCCESS;
+ lyd_diff_dup_inst_free(dup_inst);
+ return ret;
}
API LY_ERR
@@ -1037,7 +1188,7 @@
* @brief Update operations on a diff node when the new operation is NONE.
*
* @param[in] diff_match Node from the diff.
- * @param[in] cur_op Current operation of the diff node.
+ * @param[in] cur_op Current operation of @p diff_match.
* @param[in] src_diff Current source diff node.
* @return LY_ERR value.
*/
@@ -1110,7 +1261,7 @@
* @brief Update operations on a diff node when the new operation is REPLACE.
*
* @param[in] diff_match Node from the diff.
- * @param[in] cur_op Current operation of the diff node.
+ * @param[in] cur_op Current operation of @p diff_match.
* @param[in] src_diff Current source diff node.
* @return LY_ERR value.
*/
@@ -1118,7 +1269,7 @@
lyd_diff_merge_replace(struct lyd_node *diff_match, enum lyd_diff_op cur_op, const struct lyd_node *src_diff)
{
LY_ERR ret;
- const char *str_val, *meta_name;
+ const char *str_val, *meta_name, *orig_meta_name;
struct lyd_meta *meta;
const struct lys_module *mod;
const struct lyd_node_any *any;
@@ -1136,7 +1287,13 @@
/* it was created/moved somewhere, but now it will be created/moved somewhere else,
* keep orig_key/orig_value (only replace oper) and replace key/value */
assert(lysc_is_userordered(diff_match->schema));
- meta_name = (diff_match->schema->nodetype == LYS_LIST ? "key" : "value");
+ if (lysc_is_dup_inst_list(diff_match->schema)) {
+ meta_name = "position";
+ } else if (diff_match->schema->nodetype == LYS_LIST) {
+ meta_name = "key";
+ } else {
+ meta_name = "value";
+ }
lyd_diff_del_meta(diff_match, meta_name);
meta = lyd_find_meta(src_diff->meta, mod, meta_name);
@@ -1193,12 +1350,20 @@
/* change the operation */
LY_CHECK_RET(lyd_diff_change_op(diff_match, LYD_DIFF_OP_REPLACE));
- /* set orig-key and key metadata */
- meta = lyd_find_meta(src_diff->meta, mod, "orig-key");
+ /* set orig-meta and meta */
+ if (lysc_is_dup_inst_list(diff_match->schema)) {
+ meta_name = "position";
+ orig_meta_name = "orig-position";
+ } else {
+ meta_name = "key";
+ orig_meta_name = "orig-key";
+ }
+
+ meta = lyd_find_meta(src_diff->meta, mod, orig_meta_name);
LY_CHECK_ERR_RET(!meta, LOGINT(LYD_CTX(src_diff)), LY_EINT);
LY_CHECK_RET(lyd_dup_meta_single(meta, diff_match, NULL));
- meta = lyd_find_meta(src_diff->meta, mod, "key");
+ meta = lyd_find_meta(src_diff->meta, mod, meta_name);
LY_CHECK_ERR_RET(!meta, LOGINT(LYD_CTX(src_diff)), LY_EINT);
LY_CHECK_RET(lyd_dup_meta_single(meta, diff_match, NULL));
break;
@@ -1214,7 +1379,7 @@
* @brief Update operations in a diff node when the new operation is CREATE.
*
* @param[in] diff_match Node from the diff.
- * @param[in] cur_op Current operation of the diff node.
+ * @param[in] cur_op Current operation of @p diff_match.
* @param[in] src_diff Current source diff node.
* @param[in] options Diff merge options.
* @return LY_ERR value.
@@ -1225,34 +1390,72 @@
struct lyd_node *child;
const struct lysc_node_leaf *sleaf = NULL;
uint32_t trg_flags;
+ const char *meta_name, *orig_meta_name;
+ struct lyd_meta *meta, *orig_meta;
switch (cur_op) {
case LYD_DIFF_OP_DELETE:
- if ((options & LYD_DIFF_MERGE_DEFAULTS) && (diff_match->schema->nodetype == LYS_LEAF)) {
- /* we are dealing with a leaf and are handling default values specially (as explicit nodes) */
- sleaf = (struct lysc_node_leaf *)diff_match->schema;
- }
-
/* remember current flags */
trg_flags = diff_match->flags;
- if (sleaf && sleaf->dflt &&
- !sleaf->dflt->realtype->plugin->compare(sleaf->dflt, &((struct lyd_node_term *)src_diff)->value)) {
- /* we deleted it, so a default value was in-use, and it matches the created value -> operation NONE */
- LY_CHECK_RET(lyd_diff_change_op(diff_match, LYD_DIFF_OP_NONE));
- } else if (!lyd_compare_single(diff_match, src_diff, 0)) {
+ if (lysc_is_userordered(diff_match->schema)) {
+ /* get anchor metadata */
+ if (lysc_is_dup_inst_list(diff_match->schema)) {
+ meta_name = "yang:position";
+ orig_meta_name = "yang:orig-position";
+ } else if (diff_match->schema->nodetype == LYS_LIST) {
+ meta_name = "yang:key";
+ orig_meta_name = "yang:orig-key";
+ } else {
+ meta_name = "yang:value";
+ orig_meta_name = "yang:orig-value";
+ }
+ meta = lyd_find_meta(src_diff->meta, NULL, meta_name);
+ orig_meta = lyd_find_meta(diff_match->meta, NULL, orig_meta_name);
+ LY_CHECK_ERR_RET(!meta || !orig_meta, LOGINT(LYD_CTX(src_diff)), LY_EINT);
+
+ /* the (incorrect) assumption made here is that there are no previous diff nodes that would affect
+ * the anchors stored in the metadata */
+ if (strcmp(meta->value.canonical, orig_meta->value.canonical)) {
+ /* deleted + created at another position -> operation REPLACE */
+ LY_CHECK_RET(lyd_diff_change_op(diff_match, LYD_DIFF_OP_REPLACE));
+
+ /* add anchor metadata */
+ LY_CHECK_RET(lyd_dup_meta_single(meta, diff_match, NULL));
+ } else {
+ /* deleted + created at the same position -> operation NONE */
+ LY_CHECK_RET(lyd_diff_change_op(diff_match, LYD_DIFF_OP_NONE));
+
+ /* delete anchor metadata */
+ lyd_free_meta_single(orig_meta);
+ }
+ } else if (diff_match->schema->nodetype == LYS_LEAF) {
+ if (options & LYD_DIFF_MERGE_DEFAULTS) {
+ /* we are dealing with a leaf and are handling default values specially (as explicit nodes) */
+ sleaf = (struct lysc_node_leaf *)diff_match->schema;
+ }
+
+ if (sleaf && sleaf->dflt &&
+ !sleaf->dflt->realtype->plugin->compare(sleaf->dflt, &((struct lyd_node_term *)src_diff)->value)) {
+ /* we deleted it, so a default value was in-use, and it matches the created value -> operation NONE */
+ LY_CHECK_RET(lyd_diff_change_op(diff_match, LYD_DIFF_OP_NONE));
+ } else if (!lyd_compare_single(diff_match, src_diff, 0)) {
+ /* deleted + created -> operation NONE */
+ LY_CHECK_RET(lyd_diff_change_op(diff_match, LYD_DIFF_OP_NONE));
+ } else {
+ /* we deleted it, but it was created with a different value -> operation REPLACE */
+ LY_CHECK_RET(lyd_diff_change_op(diff_match, LYD_DIFF_OP_REPLACE));
+
+ /* current value is the previous one (meta) */
+ LY_CHECK_RET(lyd_new_meta(LYD_CTX(src_diff), diff_match, NULL, "yang:orig-value",
+ LYD_CANON_VALUE(diff_match), 0, NULL));
+
+ /* update the value itself */
+ LY_CHECK_RET(lyd_change_term(diff_match, LYD_CANON_VALUE(src_diff)));
+ }
+ } else {
/* deleted + created -> operation NONE */
LY_CHECK_RET(lyd_diff_change_op(diff_match, LYD_DIFF_OP_NONE));
- } else {
- /* we deleted it, but it was created with a different value -> operation REPLACE */
- LY_CHECK_RET(lyd_diff_change_op(diff_match, LYD_DIFF_OP_REPLACE));
-
- /* current value is the previous one (meta) */
- LY_CHECK_RET(lyd_new_meta(LYD_CTX(src_diff), diff_match, NULL, "yang:orig-value",
- LYD_CANON_VALUE(diff_match), 0, NULL));
-
- /* update the value itself */
- LY_CHECK_RET(lyd_change_term(diff_match, LYD_CANON_VALUE(src_diff)));
}
if (diff_match->schema->nodetype & LYD_NODE_TERM) {
@@ -1263,11 +1466,11 @@
/* update dflt flag itself */
diff_match->flags &= ~LYD_DEFAULT;
diff_match->flags |= src_diff->flags & LYD_DEFAULT;
- } else {
- /* but the operation of its children should remain DELETE */
- LY_LIST_FOR(lyd_child_no_keys(diff_match), child) {
- LY_CHECK_RET(lyd_diff_change_op(child, LYD_DIFF_OP_DELETE));
- }
+ }
+
+ /* but the operation of its children should remain DELETE */
+ LY_LIST_FOR(lyd_child_no_keys(diff_match), child) {
+ LY_CHECK_RET(lyd_diff_change_op(child, LYD_DIFF_OP_DELETE));
}
break;
default:
@@ -1282,7 +1485,7 @@
* @brief Update operations on a diff node when the new operation is DELETE.
*
* @param[in] diff_match Node from the diff.
- * @param[in] cur_op Current operation of the diff node.
+ * @param[in] cur_op Current operation of @p diff_match.
* @param[in] src_diff Current source diff node.
* @return LY_ERR value.
*/
@@ -1290,6 +1493,8 @@
lyd_diff_merge_delete(struct lyd_node *diff_match, enum lyd_diff_op cur_op, const struct lyd_node *src_diff)
{
struct lyd_node *next, *child;
+ struct lyd_meta *meta;
+ const char *meta_name;
/* we can delete only exact existing nodes */
LY_CHECK_ERR_RET(lyd_compare_single(diff_match, src_diff, 0), LOGINT(LYD_CTX(src_diff)), LY_EINT);
@@ -1303,16 +1508,46 @@
/* add orig-default meta because it is expected */
LY_CHECK_RET(lyd_new_meta(LYD_CTX(src_diff), diff_match, NULL, "yang:orig-default",
diff_match->flags & LYD_DEFAULT ? "true" : "false", 0, NULL));
- } else {
+ } else if (!lysc_is_dup_inst_list(diff_match->schema)) {
/* keep operation for all descendants (for now) */
LY_LIST_FOR(lyd_child_no_keys(diff_match), child) {
LY_CHECK_RET(lyd_diff_change_op(child, cur_op));
}
- }
+ } /* else key-less list, for which all the descendants act as keys */
break;
case LYD_DIFF_OP_REPLACE:
- /* similar to none operation but also remove the redundant attribute */
- lyd_diff_del_meta(diff_match, "orig-value");
+ /* similar to none operation but also remove the redundant metadata */
+ if (lysc_is_userordered(diff_match->schema)) {
+ if (lysc_is_dup_inst_list(diff_match->schema)) {
+ meta_name = "position";
+ } else if (diff_match->schema->nodetype == LYS_LIST) {
+ meta_name = "key";
+ } else {
+ meta_name = "value";
+ }
+ } else {
+ assert(diff_match->schema->nodetype == LYS_LEAF);
+
+ /* switch value for the original one */
+ meta = lyd_find_meta(diff_match->meta, NULL, "yang:orig-value");
+ LY_CHECK_ERR_RET(!meta, LOGINT(LYD_CTX(src_diff)), LY_EINT);
+ if (lyd_change_term(diff_match, meta->value.canonical)) {
+ LOGINT_RET(LYD_CTX(src_diff));
+ }
+
+ /* switch default for the original one, then remove the meta */
+ meta = lyd_find_meta(diff_match->meta, NULL, "yang:orig-default");
+ LY_CHECK_ERR_RET(!meta, LOGINT(LYD_CTX(src_diff)), LY_EINT);
+ diff_match->flags &= ~LYD_DEFAULT;
+ if (meta->value.boolean) {
+ diff_match->flags |= LYD_DEFAULT;
+ }
+ lyd_free_meta_single(meta);
+
+ meta_name = "orig-value";
+ }
+ lyd_diff_del_meta(diff_match, meta_name);
+
/* fall through */
case LYD_DIFF_OP_NONE:
/* it was not modified, but should be deleted -> set DELETE operation */
@@ -1346,11 +1581,16 @@
struct lyd_meta *meta, *orig_val_meta = NULL, *val_meta = NULL;
struct lyd_node *child;
const struct lys_module *mod;
- const char *str;
+ const char *str, *orig_meta_name, *meta_name;
assert(diff);
- child = lyd_child_no_keys(diff);
+ if (lysc_is_dup_inst_list(diff->schema)) {
+ /* all descendants are keys */
+ child = NULL;
+ } else {
+ child = lyd_child_no_keys(diff);
+ }
mod = ly_ctx_get_module_latest(LYD_CTX(diff), "yang");
assert(mod);
@@ -1358,9 +1598,21 @@
LY_CHECK_RET(lyd_diff_get_op(diff, &op), 0);
if ((op == LYD_DIFF_OP_REPLACE) && lysc_is_userordered(diff->schema)) {
+ /* get metadata names */
+ if (lysc_is_dup_inst_list(diff->schema)) {
+ meta_name = "position";
+ orig_meta_name = "orig-position";
+ } else if (diff->schema->nodetype == LYS_LIST) {
+ meta_name = "key";
+ orig_meta_name = "orig-key";
+ } else {
+ meta_name = "value";
+ orig_meta_name = "orig-value";
+ }
+
/* check for redundant move */
- orig_val_meta = lyd_find_meta(diff->meta, mod, (diff->schema->nodetype == LYS_LIST ? "orig-key" : "orig-value"));
- val_meta = lyd_find_meta(diff->meta, mod, (diff->schema->nodetype == LYS_LIST ? "key" : "value"));
+ orig_val_meta = lyd_find_meta(diff->meta, mod, orig_meta_name);
+ val_meta = lyd_find_meta(diff->meta, mod, meta_name);
assert(orig_val_meta && val_meta);
if (!lyd_compare_meta(orig_val_meta, val_meta)) {
@@ -1403,29 +1655,31 @@
}
/**
- * @brief Merge sysrepo diff with another diff, recursively.
+ * @brief Merge sysrepo diff subtree with another diff, recursively.
*
* @param[in] src_diff Source diff node.
* @param[in] diff_parent Current sysrepo diff parent.
* @param[in] diff_cb Optional diff callback.
* @param[in] cb_data User data for @p diff_cb.
+ * @param[in,out] dup_inst Duplicate instance cache for all @p src_diff siblings.
* @param[in] options Diff merge options.
* @param[in,out] diff Diff root node.
* @return LY_ERR value.
*/
static LY_ERR
lyd_diff_merge_r(const struct lyd_node *src_diff, struct lyd_node *diff_parent, lyd_diff_cb diff_cb, void *cb_data,
- uint16_t options, struct lyd_node **diff)
+ struct lyd_diff_dup_inst **dup_inst, uint16_t options, struct lyd_node **diff)
{
LY_ERR ret = LY_SUCCESS;
struct lyd_node *child, *diff_node = NULL;
enum lyd_diff_op src_op, cur_op;
+ struct lyd_diff_dup_inst *child_dup_inst = NULL;
/* get source node operation */
LY_CHECK_RET(lyd_diff_get_op(src_diff, &src_op));
/* find an equal node in the current diff */
- lyd_diff_find_node(diff_parent ? lyd_child_no_keys(diff_parent) : *diff, src_diff, &diff_node);
+ LY_CHECK_RET(lyd_diff_find_match(diff_parent ? lyd_child_no_keys(diff_parent) : *diff, src_diff, 1, dup_inst, &diff_node));
if (diff_node) {
/* get target (current) operation */
@@ -1438,7 +1692,7 @@
break;
case LYD_DIFF_OP_CREATE:
if ((cur_op == LYD_DIFF_OP_CREATE) && lysc_is_dup_inst_list(diff_node->schema)) {
- /* special case of creating duplicate state (leaf-)list instances */
+ /* special case of creating duplicate (leaf-)list instances */
goto add_diff;
}
@@ -1448,6 +1702,8 @@
ret = lyd_diff_merge_delete(diff_node, cur_op, src_diff);
break;
case LYD_DIFF_OP_NONE:
+ /* key-less list can never have "none" operation since all its descendants are acting as "keys" */
+ assert((src_diff->schema->nodetype != LYS_LIST) || !lysc_is_dup_inst_list(src_diff->schema));
ret = lyd_diff_merge_none(diff_node, cur_op, src_diff);
break;
default:
@@ -1466,9 +1722,18 @@
/* update diff parent */
diff_parent = diff_node;
- /* merge src_diff recursively */
- LY_LIST_FOR(lyd_child_no_keys(src_diff), child) {
- LY_CHECK_RET(lyd_diff_merge_r(child, diff_parent, diff_cb, cb_data, options, diff));
+ /* for diff purposes, all key-less list descendants actually act as keys (identifying the same instances),
+ * so there is nothing to merge for these "keys" */
+ if (!lysc_is_dup_inst_list(src_diff->schema)) {
+ /* merge src_diff recursively */
+ LY_LIST_FOR(lyd_child_no_keys(src_diff), child) {
+ ret = lyd_diff_merge_r(child, diff_parent, diff_cb, cb_data, &child_dup_inst, options, diff);
+ if (ret) {
+ break;
+ }
+ }
+ lyd_diff_dup_inst_free(child_dup_inst);
+ LY_CHECK_RET(ret);
}
} else {
add_diff:
@@ -1509,6 +1774,8 @@
lyd_diff_cb diff_cb, void *cb_data, uint16_t options)
{
const struct lyd_node *src_root;
+ struct lyd_diff_dup_inst *dup_inst = NULL;
+ LY_ERR ret = LY_SUCCESS;
LY_LIST_FOR(src_diff, src_root) {
if (mod && (lyd_owner_module(src_root) != mod)) {
@@ -1517,21 +1784,28 @@
}
/* apply relevant nodes from the diff datatree */
- LY_CHECK_RET(lyd_diff_merge_r(src_root, NULL, diff_cb, cb_data, options, diff));
+ LY_CHECK_GOTO(ret = lyd_diff_merge_r(src_root, NULL, diff_cb, cb_data, &dup_inst, options, diff), cleanup);
}
- return LY_SUCCESS;
+cleanup:
+ lyd_diff_dup_inst_free(dup_inst);
+ return ret;
}
API LY_ERR
lyd_diff_merge_tree(struct lyd_node **diff_first, struct lyd_node *diff_parent, const struct lyd_node *src_sibling,
lyd_diff_cb diff_cb, void *cb_data, uint16_t options)
{
+ LY_ERR ret;
+ struct lyd_diff_dup_inst *dup_inst = NULL;
+
if (!src_sibling) {
return LY_SUCCESS;
}
- return lyd_diff_merge_r(src_sibling, diff_parent, diff_cb, cb_data, options, diff_first);
+ ret = lyd_diff_merge_r(src_sibling, diff_parent, diff_cb, cb_data, &dup_inst, options, diff_first);
+ lyd_diff_dup_inst_free(dup_inst);
+ return ret;
}
API LY_ERR
@@ -1734,11 +2008,19 @@
case LYS_LEAFLIST:
/* leaf-list move */
LY_CHECK_GOTO(ret = lyd_diff_reverse_default(elem, mod), cleanup);
- LY_CHECK_GOTO(ret = lyd_diff_reverse_meta(elem, mod, "orig-value", "value"), cleanup);
+ if (lysc_is_dup_inst_list(elem->schema)) {
+ LY_CHECK_GOTO(ret = lyd_diff_reverse_meta(elem, mod, "orig-position", "position"), cleanup);
+ } else {
+ LY_CHECK_GOTO(ret = lyd_diff_reverse_meta(elem, mod, "orig-value", "value"), cleanup);
+ }
break;
case LYS_LIST:
/* list move */
- LY_CHECK_GOTO(ret = lyd_diff_reverse_meta(elem, mod, "orig-key", "key"), cleanup);
+ if (lysc_is_dup_inst_list(elem->schema)) {
+ LY_CHECK_GOTO(ret = lyd_diff_reverse_meta(elem, mod, "orig-position", "position"), cleanup);
+ } else {
+ LY_CHECK_GOTO(ret = lyd_diff_reverse_meta(elem, mod, "orig-key", "key"), cleanup);
+ }
break;
default:
LOGINT(LYD_CTX(src_diff));
diff --git a/src/diff.h b/src/diff.h
index b50e91b..c2f1d06 100644
--- a/src/diff.h
+++ b/src/diff.h
@@ -31,6 +31,14 @@
};
/**
+ * @brief Internal structure for remembering "used" instances of lists with duplicate instances allowed.
+ */
+struct lyd_diff_dup_inst {
+ struct ly_set *inst_set;
+ uint32_t used;
+};
+
+/**
* @brief Diff operations.
*/
enum lyd_diff_op {
@@ -49,11 +57,14 @@
* @param[in] orig_value Original value metadata to set.
* @param[in] key Key metadata to set.
* @param[in] value Value metadata to set.
+ * @param[in] position Position metadata to set.
* @param[in] orig_key Original key metadata to set.
+ * @param[in] orig_position Original position metadata to set.
* @param[in,out] diff Diff to append to.
* @return LY_ERR value.
*/
LY_ERR lyd_diff_add(const struct lyd_node *node, enum lyd_diff_op op, const char *orig_default, const char *orig_value,
- const char *key, const char *value, const char *orig_key, struct lyd_node **diff);
+ const char *key, const char *value, const char *position, const char *orig_key, const char *orig_position,
+ struct lyd_node **diff);
#endif /* LY_DIFF_H_ */
diff --git a/src/schema_compile_node.c b/src/schema_compile_node.c
index 9221ab4..d34b46d 100644
--- a/src/schema_compile_node.c
+++ b/src/schema_compile_node.c
@@ -2782,7 +2782,13 @@
if (llist->min) {
llist->flags |= LYS_MAND_TRUE;
}
- llist->max = llist_p->max ? llist_p->max : (uint32_t)-1;
+ llist->max = llist_p->max ? llist_p->max : UINT32_MAX;
+
+ if (llist->flags & LYS_CONFIG_R) {
+ /* state leaf-list is always ordered-by user */
+ llist->flags &= ~LYS_ORDBY_SYSTEM;
+ llist->flags |= LYS_ORDBY_USER;
+ }
/* checks */
if ((llist->flags & LYS_SET_DFLT) && (llist->flags & LYS_MAND_TRUE)) {
@@ -3071,7 +3077,8 @@
keystr = list_p->key;
if (!keystr) {
/* keyless list */
- list->flags |= LYS_KEYLESS;
+ list->flags &= ~LYS_ORDBY_SYSTEM;
+ list->flags |= LYS_KEYLESS | LYS_ORDBY_USER;
}
while (keystr) {
delim = strpbrk(keystr, " \t\n");
diff --git a/src/tree_data.c b/src/tree_data.c
index b353053..a3db3ba 100644
--- a/src/tree_data.c
+++ b/src/tree_data.c
@@ -1181,11 +1181,18 @@
case LYS_RPC:
case LYS_ACTION:
case LYS_LIST:
- case LYS_LEAFLIST:
/* if it exists, there is nothing to update */
*new_parent = NULL;
*new_node = NULL;
break;
+ case LYS_LEAFLIST:
+ if (!lysc_is_dup_inst_list(node->schema)) {
+ /* if it exists, there is nothing to update */
+ *new_parent = NULL;
+ *new_node = NULL;
+ break;
+ }
+ /* fallthrough */
case LYS_LEAF:
ret = lyd_change_term(node, value);
if ((ret == LY_SUCCESS) || (ret == LY_EEXIST)) {
@@ -1569,65 +1576,68 @@
static LY_ERR
lyd_new_path_check_find_lypath(struct ly_path *path, const char *str_path, const char *value, uint32_t options)
{
- LY_ERR ret = LY_SUCCESS, r;
- const struct lysc_node *schema = NULL;
+ LY_ERR r;
struct ly_path_predicate *pred;
- LY_ARRAY_COUNT_TYPE u, new_count = 0;
+ const struct lysc_node *schema = NULL;
+ LY_ARRAY_COUNT_TYPE u, new_count;
+ int create = 0;
assert(path);
/* go through all the compiled nodes */
LY_ARRAY_FOR(path, u) {
schema = path[u].node;
- new_count = u + 1;
- if ((schema->nodetype == LYS_LIST) && (path[u].pred_type == LY_PATH_PREDTYPE_NONE)) {
- if (schema->flags & LYS_KEYLESS) {
- /* creating a new keyless list instance */
- break;
- } else if ((u < LY_ARRAY_COUNT(path) - 1) || !(options & LYD_NEW_PATH_OPAQ)) {
+
+ if (lysc_is_dup_inst_list(schema)) {
+ if (path[u].pred_type == LY_PATH_PREDTYPE_NONE) {
+ /* creating a new key-less list or state leaf-list instance */
+ create = 1;
+ new_count = u;
+ } else if (path[u].pred_type != LY_PATH_PREDTYPE_POSITION) {
+ LOG_LOCSET(schema, NULL, NULL, NULL);
+ LOGVAL(schema->module->ctx, LYVE_XPATH, "Invalid predicate for %s \"%s\" in path \"%s\".",
+ lys_nodetype2str(schema->nodetype), schema->name, str_path);
+ LOG_LOCBACK(1, 0, 0, 0);
+ return LY_EINVAL;
+ }
+ } else if ((schema->nodetype == LYS_LIST) && (path[u].pred_type != LY_PATH_PREDTYPE_LIST)) {
+ if ((u < LY_ARRAY_COUNT(path) - 1) || !(options & LYD_NEW_PATH_OPAQ)) {
LOG_LOCSET(schema, NULL, NULL, NULL);
LOGVAL(schema->module->ctx, LYVE_XPATH, "Predicate missing for %s \"%s\" in path \"%s\".",
lys_nodetype2str(schema->nodetype), schema->name, str_path);
LOG_LOCBACK(1, 0, 0, 0);
return LY_EINVAL;
- } /* else creating an opaque list without keys */
- }
- }
-
- if ((schema->nodetype == LYS_LEAFLIST) && (path[new_count - 1].pred_type == LY_PATH_PREDTYPE_NONE)) {
- /* parse leafref value into a predicate, if not defined in the path */
- if (!value) {
- value = "";
- }
-
- r = LY_SUCCESS;
- if (options & LYD_NEW_PATH_OPAQ) {
- r = lys_value_validate(NULL, schema, value, strlen(value), LY_PREF_JSON, NULL);
- }
- if (!r) {
- /* store the new predicate */
- path[new_count - 1].pred_type = LY_PATH_PREDTYPE_LEAFLIST;
- LY_ARRAY_NEW_GOTO(schema->module->ctx, path[new_count - 1].predicates, pred, ret, cleanup);
-
- ret = lyd_value_store(schema->module->ctx, &pred->value, ((struct lysc_node_leaflist *)schema)->type, value,
- strlen(value), NULL, LY_PREF_JSON, NULL, LYD_HINT_DATA, schema, NULL);
- LY_CHECK_GOTO(ret, cleanup);
- ++((struct lysc_type *)pred->value.realtype)->refcount;
-
- if (schema->flags & LYS_CONFIG_R) {
- /* creating a new state leaf-list instance */
- --new_count;
+ } /* else creating an opaque list */
+ } else if ((schema->nodetype == LYS_LEAFLIST) && (path[u].pred_type != LY_PATH_PREDTYPE_LEAFLIST)) {
+ if (!value) {
+ value = "";
}
- } /* else we have opaq flag and the value is not valid, leave no predicate and then create an opaque node */
+
+ r = LY_SUCCESS;
+ if (options & LYD_NEW_PATH_OPAQ) {
+ r = lyd_value_validate(NULL, schema, value, strlen(value), NULL, NULL, NULL);
+ }
+ if (!r) {
+ /* store the new predicate so that it is used when searching for this instance */
+ path[u].pred_type = LY_PATH_PREDTYPE_LEAFLIST;
+ LY_ARRAY_NEW_RET(schema->module->ctx, path[u].predicates, pred, LY_EMEM);
+
+ LY_CHECK_RET(lyd_value_store(schema->module->ctx, &pred->value,
+ ((struct lysc_node_leaflist *)schema)->type, value, strlen(value), NULL, LY_PREF_JSON, NULL,
+ LYD_HINT_DATA, schema, NULL));
+ ++((struct lysc_type *)pred->value.realtype)->refcount;
+ } /* else we have opaq flag and the value is not valid, leave no predicate and then create an opaque node */
+ }
}
- /* hide the nodes that should always be created so they are not found */
- while (new_count < LY_ARRAY_COUNT(path)) {
- LY_ARRAY_DECREMENT(path);
+ if (create) {
+ /* hide the nodes that should always be created so they are not found */
+ while (new_count < LY_ARRAY_COUNT(path)) {
+ LY_ARRAY_DECREMENT(path);
+ }
}
-cleanup:
- return ret;
+ return LY_SUCCESS;
}
/**
@@ -1666,6 +1676,7 @@
struct ly_path *p = NULL;
struct lyd_node *nparent = NULL, *nnode = NULL, *node = NULL, *cur_parent;
const struct lysc_node *schema;
+ const struct lyd_value *val = NULL;
LY_ARRAY_COUNT_TYPE path_idx = 0, orig_count = 0;
assert(parent || ctx);
@@ -1733,27 +1744,20 @@
switch (schema->nodetype) {
case LYS_LIST:
- if (!(schema->flags & LYS_KEYLESS)) {
- if ((options & LYD_NEW_PATH_OPAQ) && (p[path_idx].pred_type == LY_PATH_PREDTYPE_NONE)) {
- /* creating opaque list without keys */
- LY_CHECK_GOTO(ret = lyd_create_opaq(ctx, schema->name, strlen(schema->name), NULL, 0,
- schema->module->name, strlen(schema->module->name), NULL, 0, NULL, LY_PREF_JSON, NULL,
- LYD_NODEHINT_LIST, &node), cleanup);
- } else {
- if (p[path_idx].pred_type != LY_PATH_PREDTYPE_LIST) {
- LOG_LOCSET(schema, NULL, NULL, NULL);
- LOGVAL(ctx, LYVE_XPATH, "Predicate missing for %s \"%s\" in path \"%s\".",
- lys_nodetype2str(schema->nodetype), schema->name, path);
- LOG_LOCBACK(1, 0, 0, 0);
- ret = LY_EINVAL;
- goto cleanup;
- }
-
- LY_CHECK_GOTO(ret = lyd_create_list(schema, p[path_idx].predicates, &node), cleanup);
- }
- break;
+ if (lysc_is_dup_inst_list(schema)) {
+ /* create key-less list instance */
+ LY_CHECK_GOTO(ret = lyd_create_inner(schema, &node), cleanup);
+ } else if ((options & LYD_NEW_PATH_OPAQ) && (p[path_idx].pred_type == LY_PATH_PREDTYPE_NONE)) {
+ /* creating opaque list without keys */
+ LY_CHECK_GOTO(ret = lyd_create_opaq(ctx, schema->name, strlen(schema->name), NULL, 0,
+ schema->module->name, strlen(schema->module->name), NULL, 0, NULL, LY_PREF_JSON, NULL,
+ LYD_NODEHINT_LIST, &node), cleanup);
+ } else {
+ /* create standard list instance */
+ assert(p[path_idx].pred_type == LY_PATH_PREDTYPE_LIST);
+ LY_CHECK_GOTO(ret = lyd_create_list(schema, p[path_idx].predicates, &node), cleanup);
}
- /* fall through */
+ break;
case LYS_CONTAINER:
case LYS_NOTIF:
case LYS_RPC:
@@ -1761,14 +1765,35 @@
LY_CHECK_GOTO(ret = lyd_create_inner(schema, &node), cleanup);
break;
case LYS_LEAFLIST:
- if ((options & LYD_NEW_PATH_OPAQ) && (p[path_idx].pred_type == LY_PATH_PREDTYPE_NONE)) {
- /* creating opaque leaf-list without value */
- LY_CHECK_GOTO(ret = lyd_create_opaq(ctx, schema->name, strlen(schema->name), NULL, 0,
- schema->module->name, strlen(schema->module->name), NULL, 0, NULL, LY_PREF_JSON, NULL,
- LYD_NODEHINT_LEAFLIST, &node), cleanup);
- } else {
- assert(p[path_idx].pred_type == LY_PATH_PREDTYPE_LEAFLIST);
+ if ((options & LYD_NEW_PATH_OPAQ) && (p[path_idx].pred_type != LY_PATH_PREDTYPE_LEAFLIST)) {
+ /* we have not checked this only for dup-inst lists, otherwise it must be opaque */
+ r = LY_EVALID;
+ if (lysc_is_dup_inst_list(schema)) {
+ /* validate value */
+ r = lyd_value_validate(NULL, schema, value ? value : "", value ? strlen(value) : 0, NULL, NULL, NULL);
+ }
+ if (r && (r != LY_EINCOMPLETE)) {
+ /* creating opaque leaf-list */
+ LY_CHECK_GOTO(ret = lyd_create_opaq(ctx, schema->name, strlen(schema->name), value,
+ value ? strlen(value) : 0, schema->module->name, strlen(schema->module->name), NULL, 0, NULL,
+ LY_PREF_JSON, NULL, LYD_NODEHINT_LEAFLIST, &node), cleanup);
+ break;
+ }
+ }
+
+ /* get value to set */
+ if (p[path_idx].pred_type == LY_PATH_PREDTYPE_LEAFLIST) {
+ val = &p[path_idx].predicates[0].value;
+ } else if (!value) {
+ value = "";
+ }
+
+ /* create a leaf-list instance */
+ if (val) {
LY_CHECK_GOTO(ret = lyd_create_term2(schema, &p[path_idx].predicates[0].value, &node), cleanup);
+ } else {
+ LY_CHECK_GOTO(ret = lyd_create_term(schema, value, strlen(value), NULL, LY_PREF_JSON, NULL,
+ LYD_HINT_DATA, NULL, &node), cleanup);
}
break;
case LYS_LEAF:
@@ -1780,23 +1805,26 @@
goto next_iter;
}
- /* make sure there is some value */
+ if (options & LYD_NEW_PATH_OPAQ) {
+ /* validate value */
+ r = lyd_value_validate(NULL, schema, value ? value : "", value ? strlen(value) : 0, NULL, NULL, NULL);
+ if (r && (r != LY_EINCOMPLETE)) {
+ /* creating opaque leaf */
+ LY_CHECK_GOTO(ret = lyd_create_opaq(ctx, schema->name, strlen(schema->name), value,
+ value ? strlen(value) : 0, schema->module->name, strlen(schema->module->name), NULL, 0, NULL,
+ LY_PREF_JSON, NULL, 0, &node), cleanup);
+ break;
+ }
+ }
+
+ /* get value to set */
if (!value) {
value = "";
}
- r = LY_SUCCESS;
- if (options & LYD_NEW_PATH_OPAQ) {
- r = lys_value_validate(NULL, schema, value, strlen(value), LY_PREF_JSON, NULL);
- }
- if (!r) {
- ret = lyd_create_term(schema, value, strlen(value), NULL, LY_PREF_JSON, NULL, LYD_HINT_DATA, NULL, &node);
- LY_CHECK_GOTO(ret, cleanup);
- } else {
- /* creating opaque leaf without value */
- LY_CHECK_GOTO(ret = lyd_create_opaq(ctx, schema->name, strlen(schema->name), NULL, 0, schema->module->name,
- strlen(schema->module->name), NULL, 0, NULL, LY_PREF_JSON, NULL, 0, &node), cleanup);
- }
+ /* create a leaf instance */
+ LY_CHECK_GOTO(ret = lyd_create_term(schema, value, strlen(value), NULL, LY_PREF_JSON, NULL, LYD_HINT_DATA,
+ NULL, &node), cleanup);
break;
case LYS_ANYDATA:
case LYS_ANYXML:
@@ -2252,10 +2280,6 @@
/* remove default flags from NP containers */
par->flags &= ~LYD_DEFAULT;
}
- if (par->schema && (par->schema->nodetype == LYS_LIST) && (par->schema->flags & LYS_KEYLESS)) {
- /* rehash key-less list */
- lyd_hash(&par->node);
- }
}
}
@@ -2292,10 +2316,6 @@
/* remove default flags from NP containers */
par->flags &= ~LYD_DEFAULT;
}
- if (par->schema && (par->schema->nodetype == LYS_LIST) && (par->schema->flags & LYS_KEYLESS)) {
- /* rehash key-less list */
- lyd_hash(&par->node);
- }
}
}
@@ -2325,10 +2345,6 @@
/* remove default flags from NP containers */
par->flags &= ~LYD_DEFAULT;
}
- if (par->schema && (par->schema->nodetype == LYS_LIST) && (par->schema->flags & LYS_KEYLESS)) {
- /* rehash key-less list */
- lyd_hash(&par->node);
- }
}
}
@@ -2613,15 +2629,6 @@
}
}
- /* check for keyless list and update its hash */
- for (iter = lyd_parent(node); iter; iter = lyd_parent(iter)) {
- if (iter->schema && (iter->schema->flags & LYS_KEYLESS)) {
- lyd_unlink_hash(iter);
- lyd_hash(iter);
- lyd_insert_hash(iter);
- }
- }
-
node->parent = NULL;
}
@@ -3350,13 +3357,6 @@
}
}
- /* rehash if needed */
- for ( ; local_parent; local_parent = local_parent->parent) {
- if ((local_parent->schema->nodetype == LYS_LIST) && (local_parent->schema->flags & LYS_KEYLESS)) {
- lyd_hash(&local_parent->node);
- }
- }
-
if (dup) {
*dup = first;
}
@@ -3802,8 +3802,9 @@
API LY_ERR
lyd_find_sibling_first(const struct lyd_node *siblings, const struct lyd_node *target, struct lyd_node **match)
{
- struct lyd_node **match_p;
+ struct lyd_node **match_p, *iter;
struct lyd_node_inner *parent;
+ ly_bool found;
LY_CHECK_ARG_RET(NULL, target, LY_EINVAL);
@@ -3816,30 +3817,35 @@
return LY_ENOTFOUND;
}
- /* find first sibling */
- if (siblings->parent) {
- siblings = siblings->parent->child;
- } else {
- while (siblings->prev->next) {
- siblings = siblings->prev;
- }
- }
+ /* get first sibling */
+ siblings = lyd_first_sibling(siblings);
parent = siblings->parent;
if (parent && parent->schema && parent->children_ht) {
assert(target->hash);
- /* find by hash */
- if (!lyht_find(parent->children_ht, &target, target->hash, (void **)&match_p)) {
- /* check even value when needed */
- if (!(target->schema->nodetype & (LYS_LIST | LYS_LEAFLIST)) || !lyd_compare_single(target, *match_p, 0)) {
- siblings = *match_p;
+ if (lysc_is_dup_inst_list(target->schema)) {
+ /* we must search the instances from beginning to find the first matching one */
+ found = 0;
+ LYD_LIST_FOR_INST(siblings, target->schema, iter) {
+ if (!lyd_compare_single(target, iter, 0)) {
+ found = 1;
+ break;
+ }
+ }
+ if (found) {
+ siblings = iter;
} else {
siblings = NULL;
}
} else {
- /* not found */
- siblings = NULL;
+ /* find by hash */
+ if (!lyht_find(parent->children_ht, &target, target->hash, (void **)&match_p)) {
+ siblings = *match_p;
+ } else {
+ /* not found */
+ siblings = NULL;
+ }
}
} else {
/* no children hash table */
@@ -3921,12 +3927,6 @@
/* find by hash */
if (!lyht_find(parent->children_ht, &schema, hash, (void **)&match_p)) {
siblings = *match_p;
- if (siblings->prev != siblings) {
- const struct lyd_node *first;
- for (first = parent->child;
- siblings != first && siblings->prev->schema == schema;
- siblings = siblings->prev) {}
- }
} else {
/* not found */
siblings = NULL;
@@ -4010,6 +4010,77 @@
}
API LY_ERR
+lyd_find_sibling_dup_inst_set(const struct lyd_node *siblings, const struct lyd_node *target, struct ly_set **set)
+{
+ struct lyd_node **match_p, *first, *iter;
+ struct lyd_node_inner *parent;
+
+ LY_CHECK_ARG_RET(NULL, target, lysc_is_dup_inst_list(target->schema), set, LY_EINVAL);
+
+ LY_CHECK_RET(ly_set_new(set));
+
+ if (!siblings || (siblings->schema && (lysc_data_parent(siblings->schema) != lysc_data_parent(target->schema)))) {
+ /* no data or schema mismatch */
+ return LY_ENOTFOUND;
+ }
+
+ /* get first sibling */
+ siblings = lyd_first_sibling(siblings);
+
+ parent = siblings->parent;
+ if (parent && parent->schema && parent->children_ht) {
+ assert(target->hash);
+
+ /* find the first instance */
+ lyd_find_sibling_first(siblings, target, &first);
+ if (first) {
+ /* add it so that it is the first in the set */
+ if (ly_set_add(*set, first, 1, NULL)) {
+ goto error;
+ }
+
+ /* find by hash */
+ if (!lyht_find(parent->children_ht, &target, target->hash, (void **)&match_p)) {
+ iter = *match_p;
+ } else {
+ /* not found */
+ iter = NULL;
+ }
+ while (iter) {
+ /* add all found nodes into the set */
+ if ((iter != first) && !lyd_compare_single(iter, target, 0) && ly_set_add(*set, iter, 1, NULL)) {
+ goto error;
+ }
+
+ /* find next instance */
+ if (lyht_find_next(parent->children_ht, &iter, iter->hash, (void **)&match_p)) {
+ iter = NULL;
+ } else {
+ iter = *match_p;
+ }
+ }
+ }
+ } else {
+ /* no children hash table */
+ LY_LIST_FOR(siblings, siblings) {
+ if (!lyd_compare_single(target, siblings, 0)) {
+ ly_set_add(*set, (void *)siblings, 1, NULL);
+ }
+ }
+ }
+
+ if (!(*set)->count) {
+ return LY_ENOTFOUND;
+ }
+ return LY_SUCCESS;
+
+error:
+ ly_set_free(*set, NULL);
+ *set = NULL;
+ return LY_EMEM;
+}
+
+API LY_ERR
lyd_find_sibling_opaq_next(const struct lyd_node *first, const char *name, struct lyd_node **match)
{
LY_CHECK_ARG_RET(NULL, name, LY_EINVAL);
diff --git a/src/tree_data.h b/src/tree_data.h
index c4c8795..dcca5c3 100644
--- a/src/tree_data.h
+++ b/src/tree_data.h
@@ -944,8 +944,8 @@
* @brief Learn the relative position of a list or leaf-list instance within other instances of the same schema node.
*
* @param[in] instance List or leaf-list instance to get the position of.
- * return 0 on error.
- * return Positive integer of the @p instance position.
+ * @return 0 on error.
+ * @return Positive integer of the @p instance position.
*/
uint32_t lyd_list_pos(const struct lyd_node *instance);
@@ -1259,7 +1259,7 @@
* and @p value is ignored. Also, if a leaf-list is being created and both a predicate is defined in @p path
* and @p value is set, the predicate is preferred.
*
- * For key-less lists and state leaf-lists, positional predicates can be used. If no preciate is used for these
+ * For key-less lists and state leaf-lists, positional predicates should be used. If no predicate is used for these
* nodes, they are always created.
*
* @param[in] parent Data parent to add to/modify, can be NULL. Note that in case a first top-level sibling is used,
@@ -1610,7 +1610,7 @@
* @ingroup datatree
* @defgroup dupoptions Data duplication options
*
- * Various options to change ::lyd_dup_single(), ::lyd_dup_siblings() and ::lyd_dup_meta_single() behavior.
+ * Various options to change ::lyd_dup_single() and ::lyd_dup_siblings() behavior.
*
* Default behavior:
* - only the specified node is duplicated without siblings, parents, or children.
@@ -1997,6 +1997,19 @@
size_t val_len, struct lyd_node **match);
/**
+ * @brief Search the given siblings for all the exact same instances of a specific node instance. Accepts only nodes
+ * that are allowed to have several exact same instances. Uses hashes to whatever extent possible.
+ *
+ * @param[in] siblings Siblings to search in including preceding and succeeding nodes.
+ * @param[in] target Target node instance to find.
+ * @param[out] set Set with all the found instances. The first item is always the first instance.
+ * @return LY_SUCCESS on success, @p set returned.
+ * @return LY_ENOTFOUND if not found, empty @p set returned.
+ * @return LY_ERR value if another error occurred.
+ */
+LY_ERR lyd_find_sibling_dup_inst_set(const struct lyd_node *siblings, const struct lyd_node *target, struct ly_set **set);
+
+/**
* @brief Search the given siblings for an opaque node with a specific name.
*
* @param[in] first First sibling to consider.
diff --git a/src/tree_data_hash.c b/src/tree_data_hash.c
index 39c5fea..a27f514 100644
--- a/src/tree_data_hash.c
+++ b/src/tree_data_hash.c
@@ -25,29 +25,6 @@
#include "tree_data.h"
#include "tree_schema.h"
-static void
-lyd_hash_keyless_list_dfs(const struct lyd_node *child, uint32_t *hash)
-{
- const struct lyd_node *iter;
-
- LY_LIST_FOR(child, iter) {
- switch (iter->schema->nodetype) {
- case LYS_CONTAINER:
- case LYS_LIST:
- lyd_hash_keyless_list_dfs(lyd_child(iter), hash);
- break;
- case LYS_LEAFLIST:
- case LYS_ANYXML:
- case LYS_ANYDATA:
- case LYS_LEAF:
- *hash = dict_hash_multi(*hash, (char *)&iter->hash, sizeof iter->hash);
- break;
- default:
- LOGINT(NULL);
- }
- }
-}
-
LY_ERR
lyd_hash(struct lyd_node *node)
{
@@ -57,25 +34,29 @@
return LY_SUCCESS;
}
+ /* hash always starts with the module and schema name */
node->hash = dict_hash_multi(0, node->schema->module->name, strlen(node->schema->module->name));
node->hash = dict_hash_multi(node->hash, node->schema->name, strlen(node->schema->name));
if (node->schema->nodetype == LYS_LIST) {
- struct lyd_node_inner *list = (struct lyd_node_inner *)node;
- if (!(node->schema->flags & LYS_KEYLESS)) {
- /* list's hash is made of its keys */
+ if (node->schema->flags & LYS_KEYLESS) {
+ /* key-less list simply adds its schema name again to the hash, just so that it differs from the first-instance hash */
+ node->hash = dict_hash_multi(node->hash, node->schema->name, strlen(node->schema->name));
+ } else {
+ struct lyd_node_inner *list = (struct lyd_node_inner *)node;
+
+ /* list hash is made up from its keys */
for (iter = list->child; iter && (iter->schema->flags & LYS_KEY); iter = iter->next) {
const char *value = LYD_CANON_VALUE(iter);
node->hash = dict_hash_multi(node->hash, value, strlen(value));
}
- } else {
- /* keyless status list */
- lyd_hash_keyless_list_dfs(list->child, &node->hash);
}
} else if (node->schema->nodetype == LYS_LEAFLIST) {
+ /* leaf-list adds its value */
const char *value = LYD_CANON_VALUE(node);
node->hash = dict_hash_multi(node->hash, value, strlen(value));
}
+
/* finish the hash */
node->hash = dict_hash_multi(node->hash, NULL, 0);
@@ -116,17 +97,6 @@
}
/**
- * @brief Comparison callback for hash table that never considers 2 values equal.
- *
- * Implementation of ::lyht_value_equal_cb.
- */
-static ly_bool
-lyd_not_equal_value_cb(void *UNUSED(val1_p), void *UNUSED(val2_p), ly_bool UNUSED(mod), void *UNUSED(cb_data))
-{
- return 0;
-}
-
-/**
* @brief Add single node into children hash table.
*
* @param[in] ht Children hash table.
@@ -137,17 +107,13 @@
static LY_ERR
lyd_insert_hash_add(struct hash_table *ht, struct lyd_node *node, ly_bool empty_ht)
{
- LY_ERR rc = LY_SUCCESS;
- lyht_value_equal_cb orig_cb = NULL;
uint32_t hash;
assert(ht && node && node->schema);
/* add node itself */
if (lyht_insert(ht, &node, node->hash, NULL)) {
- LOGINT(LYD_CTX(node));
- rc = LY_EINT;
- goto cleanup;
+ LOGINT_RET(LYD_CTX(node));
}
/* add first instance of a (leaf-)list */
@@ -161,33 +127,20 @@
/* remove any previous stored instance, only if we did not start with an empty HT */
if (!empty_ht && node->next && (node->next->schema == node->schema)) {
if (lyht_remove(ht, &node->next, hash)) {
- LOGINT(LYD_CTX(node));
- rc = LY_EINT;
- goto cleanup;
+ LOGINT_RET(LYD_CTX(node));
}
}
- if (hash == node->hash) {
- /* special case, key-less list with no children hash is equal to the first instance list hash */
- assert((node->schema->nodetype == LYS_LIST) && (node->schema->flags & LYS_KEYLESS) && !lyd_child(node));
-
- /* we must allow exact duplicates in the hash table */
- orig_cb = lyht_set_cb(ht, lyd_not_equal_value_cb);
- }
+ /* in this case there would be the exact same value twice in the hash table, not supported (by the HT) */
+ assert(hash != node->hash);
/* insert this instance as the first (leaf-)list instance */
if (lyht_insert(ht, &node, hash, NULL)) {
- LOGINT(LYD_CTX(node));
- rc = LY_EINT;
- goto cleanup;
+ LOGINT_RET(LYD_CTX(node));
}
}
-cleanup:
- if (orig_cb) {
- lyht_set_cb(ht, orig_cb);
- }
- return rc;
+ return LY_SUCCESS;
}
LY_ERR
diff --git a/src/tree_schema.h b/src/tree_schema.h
index 70913cf..9be02a3 100644
--- a/src/tree_schema.h
+++ b/src/tree_schema.h
@@ -899,10 +899,11 @@
#define LYS_KEY 0x0100 /**< flag for leafs being a key of a list, applicable only to ::lysc_node_leaf */
#define LYS_KEYLESS 0x0200 /**< flag for list without any key, applicable only to ::lysc_node_list */
#define LYS_FENABLED 0x20 /**< feature enabled flag, applicable only to ::lysp_feature. */
-#define LYS_ORDBY_SYSTEM 0x80 /**< ordered-by user lists, applicable only to ::lysc_node_leaflist/::lysp_node_leaflist and
- ::lysc_node_list/::lysp_node_list */
-#define LYS_ORDBY_USER 0x40 /**< ordered-by user lists, applicable only to ::lysc_node_leaflist/::lysp_node_leaflist and
- ::lysc_node_list/::lysp_node_list */
+#define LYS_ORDBY_SYSTEM 0x80 /**< ordered-by system configuration lists, applicable only to
+ ::lysc_node_leaflist/::lysp_node_leaflist and ::lysc_node_list/::lysp_node_list */
+#define LYS_ORDBY_USER 0x40 /**< ordered-by user configuration lists, applicable only to
+ ::lysc_node_leaflist/::lysp_node_leaflist and ::lysc_node_list/::lysp_node_list;
+ is always set for state leaf-lists, and key-less lists */
#define LYS_ORDBY_MASK 0x60 /**< mask for ordered-by values */
#define LYS_YINELEM_TRUE 0x80 /**< yin-element true for extension's argument */
#define LYS_YINELEM_FALSE 0x0100 /**< yin-element false for extension's argument */
@@ -1988,14 +1989,14 @@
((!lysc_node || (lysc_node->nodetype != LYS_CONTAINER) || (lysc_node->flags & LYS_PRESENCE)) ? 0 : 1)
/**
- * @brief Examine whether a node is a key-less list or a state leaf-list.
+ * @brief Examine whether a node is a key-less list or a non-configuration leaf-list.
*
* @param[in] lysc_node Schema node to examine.
* @return Boolean value whether the @p node is a list with duplicate instances allowed.
*/
#define lysc_is_dup_inst_list(lysc_node) \
((lysc_node && (((lysc_node->nodetype == LYS_LIST) && (lysc_node->flags & LYS_KEYLESS)) || \
- ((lysc_node->nodetype == LYS_LEAFLIST) && (lysc_node->flags & LYS_CONFIG_R)))) ? 1 : 0)
+ ((lysc_node->nodetype == LYS_LEAFLIST) && !(lysc_node->flags & LYS_CONFIG_W)))) ? 1 : 0)
/**
* @brief Check whether the schema node data instance existence depends on any when conditions.
diff --git a/src/validation.c b/src/validation.c
index 27d5371..86d47d8 100644
--- a/src/validation.c
+++ b/src/validation.c
@@ -3,7 +3,7 @@
* @author Michal Vasko <mvasko@cesnet.cz>
* @brief Validation
*
- * Copyright (c) 2019 CESNET, z.s.p.o.
+ * Copyright (c) 2019 - 2021 CESNET, z.s.p.o.
*
* This source code is licensed under BSD 3-Clause License (the "License").
* You may not use this file except in compliance with the License.
@@ -12,6 +12,7 @@
* https://opensource.org/licenses/BSD-3-Clause
*/
#define _POSIX_C_SOURCE 200809L /* strdup */
+#define _GNU_SOURCE /* asprintf */
#include "validation.h"
@@ -46,41 +47,58 @@
LY_ERR ret = LY_SUCCESS;
struct lyd_node *new_diff = NULL;
const struct lyd_node *prev_inst;
- char *key = NULL, *value = NULL;
+ char *key = NULL, *value = NULL, *position = NULL;
size_t buflen = 0, bufused = 0;
+ uint32_t pos;
assert((op == LYD_DIFF_OP_DELETE) || (op == LYD_DIFF_OP_CREATE));
if ((op == LYD_DIFF_OP_CREATE) && lysc_is_userordered(node->schema)) {
- if (node->prev->next && (node->prev->schema == node->schema)) {
- prev_inst = node->prev;
- } else {
- /* first instance */
- prev_inst = NULL;
- }
+ if (lysc_is_dup_inst_list(node->schema)) {
+ pos = lyd_list_pos(node);
- if (node->schema->nodetype == LYS_LIST) {
- /* generate key meta */
- if (prev_inst) {
- LY_CHECK_GOTO(ret = lyd_path_list_predicate(prev_inst, &key, &buflen, &bufused, 0), cleanup);
+ /* generate position meta */
+ if (pos > 1) {
+ if (asprintf(&position, "%" PRIu32, pos - 1) == -1) {
+ LOGMEM(LYD_CTX(node));
+ ret = LY_EMEM;
+ goto cleanup;
+ }
} else {
- key = strdup("");
- LY_CHECK_ERR_GOTO(!key, LOGMEM(LYD_CTX(node)); ret = LY_EMEM, cleanup);
+ position = strdup("");
+ LY_CHECK_ERR_GOTO(!position, LOGMEM(LYD_CTX(node)); ret = LY_EMEM, cleanup);
}
} else {
- /* generate value meta */
- if (prev_inst) {
- value = strdup(LYD_CANON_VALUE(prev_inst));
- LY_CHECK_ERR_GOTO(!value, LOGMEM(LYD_CTX(node)); ret = LY_EMEM, cleanup);
+ if (node->prev->next && (node->prev->schema == node->schema)) {
+ prev_inst = node->prev;
} else {
- value = strdup("");
- LY_CHECK_ERR_GOTO(!value, LOGMEM(LYD_CTX(node)); ret = LY_EMEM, cleanup);
+ /* first instance */
+ prev_inst = NULL;
+ }
+
+ if (node->schema->nodetype == LYS_LIST) {
+ /* generate key meta */
+ if (prev_inst) {
+ LY_CHECK_GOTO(ret = lyd_path_list_predicate(prev_inst, &key, &buflen, &bufused, 0), cleanup);
+ } else {
+ key = strdup("");
+ LY_CHECK_ERR_GOTO(!key, LOGMEM(LYD_CTX(node)); ret = LY_EMEM, cleanup);
+ }
+ } else {
+ /* generate value meta */
+ if (prev_inst) {
+ value = strdup(LYD_CANON_VALUE(prev_inst));
+ LY_CHECK_ERR_GOTO(!value, LOGMEM(LYD_CTX(node)); ret = LY_EMEM, cleanup);
+ } else {
+ value = strdup("");
+ LY_CHECK_ERR_GOTO(!value, LOGMEM(LYD_CTX(node)); ret = LY_EMEM, cleanup);
+ }
}
}
}
/* create new diff tree */
- LY_CHECK_GOTO(ret = lyd_diff_add(node, op, NULL, NULL, key, value, NULL, &new_diff), cleanup);
+ LY_CHECK_GOTO(ret = lyd_diff_add(node, op, NULL, NULL, key, value, position, NULL, NULL, &new_diff), cleanup);
/* merge into existing diff */
ret = lyd_diff_merge_all(diff, new_diff, 0);
@@ -89,6 +107,7 @@
lyd_free_tree(new_diff);
free(key);
free(value);
+ free(position);
return ret;
}
@@ -370,8 +389,7 @@
assert(node->flags & LYD_NEW);
/* key-less list or non-configuration leaf-list */
- if (((node->schema->nodetype == LYS_LIST) && (node->schema->flags & LYS_KEYLESS)) ||
- ((node->schema->nodetype == LYS_LEAFLIST) && !(node->schema->flags & LYS_CONFIG_W))) {
+ if (lysc_is_dup_inst_list(node->schema)) {
/* duplicate instances allowed */
return LY_SUCCESS;
}
diff --git a/tests/utests/data/test_diff.c b/tests/utests/data/test_diff.c
index 6964764..81850f8 100644
--- a/tests/utests/data/test_diff.c
+++ b/tests/utests/data/test_diff.c
@@ -38,13 +38,13 @@
CHECK_PARSE_LYD(XML_2, model_2);\
CHECK_PARSE_LYD(XML_3, model_3);\
/* diff1 */ \
- struct lyd_node * diff1;\
+ struct lyd_node *diff1;\
CHECK_PARSE_LYD_DIFF(model_1, model_2, diff1); \
CHECK_LYD_STRING(diff1, DIFF_1); \
assert_int_equal(lyd_diff_apply_all(&model_1, diff1), LY_SUCCESS); \
CHECK_LYD(model_1, model_2); \
/* diff2 */ \
- struct lyd_node * diff2;\
+ struct lyd_node *diff2;\
CHECK_PARSE_LYD_DIFF(model_2, model_3, diff2); \
CHECK_LYD_STRING(diff2, DIFF_2); \
assert_int_equal(lyd_diff_apply_all(&model_2, diff2), LY_SUCCESS);\
@@ -108,6 +108,18 @@
" ordered-by user;\n"
" }\n"
"\n"
+ " list ul {\n"
+ " key \"l1\";\n"
+ " ordered-by user;\n"
+ " leaf l1 {\n"
+ " type string;\n"
+ " }\n"
+ "\n"
+ " leaf l2 {\n"
+ " type int32;\n"
+ " }\n"
+ " }\n"
+ "\n"
" leaf-list dllist {\n"
" type uint8;\n"
" default \"1\";\n"
@@ -190,6 +202,21 @@
" }\n"
" }\n"
" }\n"
+ " list kl {\n"
+ " config \"false\";\n"
+ " leaf l1 {\n"
+ " type string;\n"
+ " }\n"
+ "\n"
+ " leaf l2 {\n"
+ " type int32;\n"
+ " }\n"
+ " }\n"
+ "\n"
+ " leaf-list kll {\n"
+ " config \"false\";\n"
+ " type string;\n"
+ " }\n"
" }\n"
"\n"
" container hidden {\n"
@@ -691,6 +718,265 @@
}
static void
+test_userord_list(void **state)
+{
+ (void) state;
+ const char *xml1 =
+ "<df xmlns=\"urn:libyang:tests:defaults\">\n"
+ " <ul>\n"
+ " <l1>a</l1>\n"
+ " <l2>1</l2>\n"
+ " </ul>\n"
+ " <ul>\n"
+ " <l1>b</l1>\n"
+ " <l2>2</l2>\n"
+ " </ul>\n"
+ " <ul>\n"
+ " <l1>c</l1>\n"
+ " <l2>3</l2>\n"
+ " </ul>\n"
+ "</df>\n";
+ const char *xml2 =
+ "<df xmlns=\"urn:libyang:tests:defaults\">\n"
+ " <ul>\n"
+ " <l1>a</l1>\n"
+ " <l2>11</l2>\n"
+ " </ul>\n"
+ " <ul>\n"
+ " <l1>c</l1>\n"
+ " <l2>3</l2>\n"
+ " </ul>\n"
+ "</df>\n";
+ const char *xml3 =
+ "<df xmlns=\"urn:libyang:tests:defaults\">\n"
+ " <ul>\n"
+ " <l1>c</l1>\n"
+ " <l2>33</l2>\n"
+ " </ul>\n"
+ " <ul>\n"
+ " <l1>b</l1>\n"
+ " <l2>2</l2>\n"
+ " </ul>\n"
+ "</df>\n";
+
+ const char *out_diff_1 =
+ "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
+ " <ul>\n"
+ " <l1>a</l1>\n"
+ " <l2 yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"1\">11</l2>\n"
+ " </ul>\n"
+ " <ul yang:operation=\"delete\" yang:orig-key=\"[l1='a']\">\n"
+ " <l1>b</l1>\n"
+ " <l2>2</l2>\n"
+ " </ul>\n"
+ "</df>\n";
+ const char *out_diff_2 =
+ "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
+ " <ul yang:operation=\"delete\" yang:orig-key=\"\">\n"
+ " <l1>a</l1>\n"
+ " <l2>11</l2>\n"
+ " </ul>\n"
+ " <ul yang:operation=\"none\">\n"
+ " <l1>c</l1>\n"
+ " <l2 yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"3\">33</l2>\n"
+ " </ul>\n"
+ " <ul yang:operation=\"create\" yang:key=\"[l1='c']\">\n"
+ " <l1>b</l1>\n"
+ " <l2>2</l2>\n"
+ " </ul>\n"
+ "</df>\n";
+ const char *out_merge =
+ "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
+ " <ul yang:operation=\"delete\">\n"
+ " <l1>a</l1>\n"
+ " <l2 yang:operation=\"delete\">1</l2>\n"
+ " </ul>\n"
+ " <ul yang:orig-key=\"[l1='a']\" yang:operation=\"replace\" yang:key=\"[l1='c']\">\n"
+ " <l1>b</l1>\n"
+ " </ul>\n"
+ " <ul yang:operation=\"none\">\n"
+ " <l1>c</l1>\n"
+ " <l2 yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"3\">33</l2>\n"
+ " </ul>\n"
+ "</df>\n";
+
+ TEST_DIFF_3(xml1, xml2, xml3, out_diff_1, out_diff_2, out_merge);
+}
+
+static void
+test_keyless_list(void **state)
+{
+ (void) state;
+ const char *xml1 = "<df xmlns=\"urn:libyang:tests:defaults\">\n"
+ " <kl>\n"
+ " <l1>a</l1>\n"
+ " <l2>1</l2>\n"
+ " </kl>\n"
+ " <kl>\n"
+ " <l1>b</l1>\n"
+ " <l2>2</l2>\n"
+ " </kl>\n"
+ " <kl>\n"
+ " <l1>c</l1>\n"
+ " <l2>3</l2>\n"
+ " </kl>\n"
+ "</df>\n";
+ const char *xml2 = "<df xmlns=\"urn:libyang:tests:defaults\">\n"
+ " <kl>\n"
+ " <l1>b</l1>\n"
+ " <l2>2</l2>\n"
+ " </kl>\n"
+ " <kl>\n"
+ " <l1>a</l1>\n"
+ " <l2>1</l2>\n"
+ " </kl>\n"
+ " <kl>\n"
+ " <l1>a</l1>\n"
+ " <l2>1</l2>\n"
+ " </kl>\n"
+ "</df>\n";
+ const char *xml3 = "<df xmlns=\"urn:libyang:tests:defaults\">\n"
+ " <kl>\n"
+ " <l1>c</l1>\n"
+ " </kl>\n"
+ " <kl>\n"
+ " <l2>4</l2>\n"
+ " </kl>\n"
+ " <kl>\n"
+ " <l1>e</l1>\n"
+ " <l2>5</l2>\n"
+ " </kl>\n"
+ " <kl>\n"
+ " <l1>f</l1>\n"
+ " <l2>6</l2>\n"
+ " </kl>\n"
+ "</df>\n";
+
+ const char *out_diff_1 =
+ "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
+ " <kl yang:operation=\"delete\" yang:orig-position=\"2\">\n"
+ " <l1>c</l1>\n"
+ " <l2>3</l2>\n"
+ " </kl>\n"
+ " <kl yang:operation=\"replace\" yang:position=\"\" yang:orig-position=\"1\">\n"
+ " <l1>b</l1>\n"
+ " <l2>2</l2>\n"
+ " </kl>\n"
+ " <kl yang:operation=\"create\" yang:position=\"2\">\n"
+ " <l1>a</l1>\n"
+ " <l2>1</l2>\n"
+ " </kl>\n"
+ "</df>\n";
+ const char *out_diff_2 =
+ "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
+ " <kl yang:operation=\"delete\" yang:orig-position=\"\">\n"
+ " <l1>b</l1>\n"
+ " <l2>2</l2>\n"
+ " </kl>\n"
+ " <kl yang:operation=\"delete\" yang:orig-position=\"\">\n"
+ " <l1>a</l1>\n"
+ " <l2>1</l2>\n"
+ " </kl>\n"
+ " <kl yang:operation=\"delete\" yang:orig-position=\"\">\n"
+ " <l1>a</l1>\n"
+ " <l2>1</l2>\n"
+ " </kl>\n"
+ " <kl yang:operation=\"create\" yang:position=\"\">\n"
+ " <l1>c</l1>\n"
+ " </kl>\n"
+ " <kl yang:operation=\"create\" yang:position=\"1\">\n"
+ " <l2>4</l2>\n"
+ " </kl>\n"
+ " <kl yang:operation=\"create\" yang:position=\"2\">\n"
+ " <l1>e</l1>\n"
+ " <l2>5</l2>\n"
+ " </kl>\n"
+ " <kl yang:operation=\"create\" yang:position=\"3\">\n"
+ " <l1>f</l1>\n"
+ " <l2>6</l2>\n"
+ " </kl>\n"
+ "</df>\n";
+ const char *out_merge =
+ "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
+ " <kl yang:operation=\"delete\" yang:orig-position=\"2\">\n"
+ " <l1>c</l1>\n"
+ " <l2>3</l2>\n"
+ " </kl>\n"
+ " <kl yang:orig-position=\"1\" yang:operation=\"delete\">\n"
+ " <l1>b</l1>\n"
+ " <l2>2</l2>\n"
+ " </kl>\n"
+ " <kl yang:orig-position=\"\" yang:operation=\"delete\">\n"
+ " <l1>a</l1>\n"
+ " <l2>1</l2>\n"
+ " </kl>\n"
+ " <kl yang:position=\"\" yang:operation=\"create\">\n"
+ " <l1>c</l1>\n"
+ " </kl>\n"
+ " <kl yang:position=\"1\" yang:operation=\"create\">\n"
+ " <l2>4</l2>\n"
+ " </kl>\n"
+ " <kl yang:position=\"2\" yang:operation=\"create\">\n"
+ " <l1>e</l1>\n"
+ " <l2>5</l2>\n"
+ " </kl>\n"
+ " <kl yang:position=\"3\" yang:operation=\"create\">\n"
+ " <l1>f</l1>\n"
+ " <l2>6</l2>\n"
+ " </kl>\n"
+ "</df>\n";
+
+ TEST_DIFF_3(xml1, xml2, xml3, out_diff_1, out_diff_2, out_merge);
+}
+
+static void
+test_state_llist(void **state)
+{
+ (void) state;
+ const char *xml1 = "<df xmlns=\"urn:libyang:tests:defaults\">\n"
+ " <kll>a</kll>\n"
+ " <kll>b</kll>\n"
+ " <kll>c</kll>\n"
+ "</df>\n";
+ const char *xml2 = "<df xmlns=\"urn:libyang:tests:defaults\">\n"
+ " <kll>b</kll>\n"
+ " <kll>c</kll>\n"
+ " <kll>a</kll>\n"
+ " <kll>a</kll>\n"
+ " <kll>a</kll>\n"
+ "</df>\n";
+ const char *xml3 = "<df xmlns=\"urn:libyang:tests:defaults\">\n"
+ " <kll>a</kll>\n"
+ " <kll>d</kll>\n"
+ " <kll>a</kll>\n"
+ "</df>\n";
+
+ const char *out_diff_1 =
+ "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
+ " <kll yang:operation=\"replace\" yang:orig-default=\"false\" yang:position=\"\" yang:orig-position=\"1\">b</kll>\n"
+ " <kll yang:operation=\"replace\" yang:orig-default=\"false\" yang:position=\"1\" yang:orig-position=\"2\">c</kll>\n"
+ " <kll yang:operation=\"create\" yang:position=\"3\">a</kll>\n"
+ " <kll yang:operation=\"create\" yang:position=\"4\">a</kll>\n"
+ "</df>\n";
+ const char *out_diff_2 =
+ "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
+ " <kll yang:operation=\"delete\" yang:orig-position=\"\">b</kll>\n"
+ " <kll yang:operation=\"delete\" yang:orig-position=\"\">c</kll>\n"
+ " <kll yang:operation=\"delete\" yang:orig-position=\"2\">a</kll>\n"
+ " <kll yang:operation=\"create\" yang:position=\"1\">d</kll>\n"
+ "</df>\n";
+ const char *out_merge =
+ "<df xmlns=\"urn:libyang:tests:defaults\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
+ " <kll yang:orig-default=\"false\" yang:orig-position=\"1\" yang:operation=\"delete\">b</kll>\n"
+ " <kll yang:orig-default=\"false\" yang:orig-position=\"2\" yang:operation=\"delete\">c</kll>\n"
+ " <kll yang:operation=\"create\" yang:position=\"4\">a</kll>\n"
+ " <kll yang:position=\"1\" yang:operation=\"create\">d</kll>\n"
+ "</df>\n";
+
+ TEST_DIFF_3(xml1, xml2, xml3, out_diff_1, out_diff_2, out_merge);
+}
+
+static void
test_wd(void **state)
{
(void) state;
@@ -787,6 +1073,9 @@
UTEST(test_userord_llist, setup),
UTEST(test_userord_llist2, setup),
UTEST(test_userord_mix, setup),
+ UTEST(test_userord_list, setup),
+ UTEST(test_keyless_list, setup),
+ UTEST(test_state_llist, setup),
UTEST(test_wd, setup),
};
diff --git a/tests/utests/data/test_new.c b/tests/utests/data/test_new.c
index 314bed4..eee02f0 100644
--- a/tests/utests/data/test_new.c
+++ b/tests/utests/data/test_new.c
@@ -40,12 +40,16 @@
" }\n"
" container c {\n"
" leaf-list x {\n"
- " type string;\n"
+ " type string;\n"
" }\n"
" }\n"
" anydata any {\n"
" config false;\n"
" }\n"
+ " leaf-list ll2 {\n"
+ " config false;\n"
+ " type string;\n"
+ " }\n"
" list l2 {\n"
" config false;\n"
" container c {\n"
@@ -54,6 +58,17 @@
" }\n"
" }\n"
" }\n"
+ " container c2 {\n"
+ " config false;\n"
+ " list l3 {\n"
+ " leaf x {\n"
+ " type string;\n"
+ " }\n"
+ " leaf y {\n"
+ " type string;\n"
+ " }\n"
+ " }\n"
+ " }\n"
" rpc oper {\n"
" input {\n"
" leaf param {\n"
@@ -185,8 +200,10 @@
{
LY_ERR ret;
struct lyd_node *root, *node, *parent;
+ const struct lys_module *mod;
+ char *str;
- UTEST_ADD_MODULE(schema_a, LYS_IN_YANG, NULL, NULL);
+ UTEST_ADD_MODULE(schema_a, LYS_IN_YANG, NULL, &mod);
/* create 2 nodes */
ret = lyd_new_path2(NULL, UTEST_LYCTX, "/a:c/x[.='val']", "vvv", 0, 0, &root, &node);
@@ -236,27 +253,95 @@
lyd_free_tree(root);
- /* try LYD_NEWOPT_UPDATE */
- ret = lyd_new_path2(NULL, UTEST_LYCTX, "/a:l2[1]/c/x", "val", 0, 0, &root, &node);
+ /* key-less list */
+ ret = lyd_new_path2(NULL, UTEST_LYCTX, "/a:c2/l3/x", "val1", 0, 0, &root, &node);
assert_int_equal(ret, LY_SUCCESS);
assert_non_null(root);
assert_string_equal(node->schema->name, "x");
- assert_string_equal("val", LYD_CANON_VALUE(node));
+ assert_string_equal("val1", LYD_CANON_VALUE(node));
- ret = lyd_new_path2(root, NULL, "/a:l2[1]/c/x", "val", 0, 0, NULL, &node);
+ ret = lyd_new_path2(root, NULL, "/a:c2/l3[1]", NULL, 0, 0, NULL, &node);
assert_int_equal(ret, LY_EEXIST);
- ret = lyd_new_path2(root, NULL, "/a:l2[1]/c/x", "val", 0, LYD_NEW_PATH_UPDATE, NULL, &node);
+ ret = lyd_new_path2(root, NULL, "/a:c2/l3[2]/x", "val2", 0, 0, NULL, &node);
assert_int_equal(ret, LY_SUCCESS);
- assert_null(node);
- ret = lyd_new_path2(root, NULL, "/a:l2[1]/c/x", "val2", 0, LYD_NEW_PATH_UPDATE, NULL, &node);
+ ret = lyd_new_path2(root, NULL, "/a:c2/l3/x", "val3", 0, 0, NULL, &node);
assert_int_equal(ret, LY_SUCCESS);
assert_non_null(node);
- assert_string_equal(node->schema->name, "x");
- assert_string_equal("val2", LYD_CANON_VALUE(node));
- lyd_free_tree(root);
+ ret = lyd_new_path2(root, NULL, "/a:c2/l3[4]/x", "empty", 0, 0, NULL, &node);
+ assert_int_equal(ret, LY_SUCCESS);
+ assert_non_null(node);
+
+ ret = lyd_new_path2(root, NULL, "/a:c2/l3[4]/x", "val4", 0, LYD_NEW_PATH_UPDATE, NULL, &node);
+ assert_int_equal(ret, LY_SUCCESS);
+ assert_non_null(node);
+
+ ret = lyd_new_path2(root, NULL, "/a:c2/l3[5]/x", "val5", 0, 0, NULL, &node);
+ assert_int_equal(ret, LY_SUCCESS);
+ assert_non_null(node);
+
+ ret = lyd_new_path2(root, NULL, "/a:c2/l3[6]/x", "val6", 0, 0, NULL, &node);
+ assert_int_equal(ret, LY_SUCCESS);
+ assert_non_null(node);
+
+ lyd_print_mem(&str, root, LYD_XML, LYD_PRINT_WITHSIBLINGS);
+ assert_string_equal(str,
+ "<c2 xmlns=\"urn:tests:a\">\n"
+ " <l3>\n"
+ " <x>val1</x>\n"
+ " </l3>\n"
+ " <l3>\n"
+ " <x>val2</x>\n"
+ " </l3>\n"
+ " <l3>\n"
+ " <x>val3</x>\n"
+ " </l3>\n"
+ " <l3>\n"
+ " <x>val4</x>\n"
+ " </l3>\n"
+ " <l3>\n"
+ " <x>val5</x>\n"
+ " </l3>\n"
+ " <l3>\n"
+ " <x>val6</x>\n"
+ " </l3>\n"
+ "</c2>\n");
+ free(str);
+ lyd_free_siblings(root);
+
+ /* state leaf-list */
+ ret = lyd_new_path2(NULL, UTEST_LYCTX, "/a:ll2", "val_first", 0, 0, &root, &node);
+ assert_int_equal(ret, LY_SUCCESS);
+ assert_non_null(root);
+ assert_string_equal(node->schema->name, "ll2");
+ assert_string_equal("val_first", LYD_CANON_VALUE(node));
+
+ ret = lyd_new_path2(root, NULL, "/a:ll2[1]", "", 0, 0, NULL, &node);
+ assert_int_equal(ret, LY_EEXIST);
+
+ ret = lyd_new_path2(root, NULL, "/a:ll2[2]", "val2", 0, 0, NULL, &node);
+ assert_int_equal(ret, LY_SUCCESS);
+
+ ret = lyd_new_path2(root, NULL, "/a:ll2[1]", "val", 0, LYD_NEW_PATH_UPDATE, NULL, &node);
+ assert_int_equal(ret, LY_SUCCESS);
+ assert_non_null(node);
+
+ ret = lyd_new_path2(root, UTEST_LYCTX, "/a:ll2", "val3", 0, 0, NULL, &node);
+ assert_int_equal(ret, LY_SUCCESS);
+ assert_non_null(node);
+
+ ret = lyd_new_path2(root, NULL, "/a:ll2[3][.='val3']", NULL, 0, 0, NULL, &node);
+ assert_int_equal(ret, LY_EVALID);
+
+ lyd_print_mem(&str, root, LYD_XML, LYD_PRINT_WITHSIBLINGS);
+ assert_string_equal(str,
+ "<ll2 xmlns=\"urn:tests:a\">val</ll2>\n"
+ "<ll2 xmlns=\"urn:tests:a\">val2</ll2>\n"
+ "<ll2 xmlns=\"urn:tests:a\">val3</ll2>\n");
+ free(str);
+ lyd_free_siblings(root);
}
static void
diff --git a/tests/utests/data/test_tree_data.c b/tests/utests/data/test_tree_data.c
index 5dbdbe9..b3fe51c 100644
--- a/tests/utests/data/test_tree_data.c
+++ b/tests/utests/data/test_tree_data.c
@@ -380,7 +380,7 @@
LY_PATH_TARGET_SINGLE, LY_PREF_JSON, NULL, NULL, &path));
term = lyd_target(path, tree);
- const int unsigned flag = LYS_CONFIG_R | LYS_SET_ENUM | LYS_ORDBY_SYSTEM;
+ const int unsigned flag = LYS_CONFIG_R | LYS_SET_ENUM | LYS_ORDBY_USER;
CHECK_LYSC_NODE(term->schema, NULL, 0, flag, 1, "d", 0, LYS_LEAFLIST, 1, 0, NULL, 0);
assert_string_equal(LYD_CANON_VALUE(term), "b");
diff --git a/tests/utests/extensions/test_yangdata.c b/tests/utests/extensions/test_yangdata.c
index 7bf1cc6..5e5cdcc 100644
--- a/tests/utests/extensions/test_yangdata.c
+++ b/tests/utests/extensions/test_yangdata.c
@@ -46,7 +46,7 @@
" list l {\n" /* no key */
" min-elements 0;\n"
" max-elements 4294967295;\n"
- " ordered-by system;\n"
+ " ordered-by user;\n"
" status current;\n"
" leaf x {\n"
" type string;\n"
diff --git a/tests/utests/node/list.c b/tests/utests/node/list.c
index 266e0a3..4753121 100644
--- a/tests/utests/node/list.c
+++ b/tests/utests/node/list.c
@@ -62,14 +62,14 @@
"}");
UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
lysc_leaf = (void *)mod->compiled->data;
- CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, 0x85, 1, "user", 0, \
+ CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "user", 0, \
0, 0, 0, 0, 1, 0xffffffff, 0, 0, 0, 1, 0);
lysc_node = lysc_leaf->child;
- CHECK_LYSC_NODE(lysc_node, 0, 0, 0x105, 1, "uid", 1, LYS_LEAF, 1, 0, 0, 0);
+ CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "uid", 1, LYS_LEAF, 1, 0, 0, 0);
lysc_node = lysc_node->next;
- CHECK_LYSC_NODE(lysc_node, 0, 0, 0x85, 1, "name", 1, LYS_LEAF, 1, 0, 0, 0);
+ CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_UNIQUE, 1, "name", 1, LYS_LEAF, 1, 0, 0, 0);
lysc_node = lysc_node->next;
- CHECK_LYSC_NODE(lysc_node, 0, 0, 0x5, 1, "group", 0, LYS_LEAF, 1, 0, 0, 0);
+ CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR, 1, "group", 0, LYS_LEAF, 1, 0, 0, 0);
schema = MODULE_CREATE_YANG("T1", "list user {"
"key uid;"
@@ -81,12 +81,12 @@
"}");
UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
lysc_leaf = (void *)mod->compiled->data;
- CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, 0x85, 1, "user", 0, \
+ CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "user", 0, \
0, 0, 0, 0, 1, 0xffffffff, 0, 0, 0, 0, 0);
lysc_node = lysc_leaf->child;
- CHECK_LYSC_NODE(lysc_node, 0, 0, 0x105, 1, "uid", 1, LYS_LEAF, 1, 0, 0, 0);
+ CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "uid", 1, LYS_LEAF, 1, 0, 0, 0);
lysc_node = lysc_node->next;
- CHECK_LYSC_NODE(lysc_node, 0, 0, 0x5, 1, "name", 0, LYS_CONTAINER, 1, 0, 0, 0);
+ CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR, 1, "name", 0, LYS_CONTAINER, 1, 0, 0, 0);
schema = MODULE_CREATE_YANG("T2", "list grup {"
"key \"guid\";"
@@ -95,12 +95,12 @@
"}");
UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
lysc_leaf = (void *)mod->compiled->data;
- CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, 0x85, 1, "grup", 0, \
+ CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "grup", 0, \
0, 0, 0, 0, 1, 0xffffffff, 0, 0, 0, 0, 0);
lysc_node = lysc_leaf->child;
- CHECK_LYSC_NODE(lysc_node, 0, 0, 0x105, 1, "guid", 1, LYS_LEAF, 1, 0, 0, 0);
+ CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "guid", 1, LYS_LEAF, 1, 0, 0, 0);
lysc_node = lysc_node->next;
- CHECK_LYSC_NODE(lysc_node, 0, 0, 0x85, 1, "users", 0, LYS_LIST, 1, 0, 0, 0);
+ CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "users", 0, LYS_LIST, 1, 0, 0, 0);
/* restriction */
schema = MODULE_CREATE_YANG("T3", "list grup {"
@@ -112,12 +112,12 @@
"}");
UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
lysc_leaf = (void *)mod->compiled->data;
- CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, 0xa5, 1, "grup", 0, \
- 0, 0, 0, 0, 1, 20, 10, 0, 0, 0, 0);
+ CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_MAND_TRUE | LYS_ORDBY_SYSTEM, 1, \
+ "grup", 0, 0, 0, 0, 0, 1, 20, 10, 0, 0, 0, 0);
lysc_node = lysc_leaf->child;
- CHECK_LYSC_NODE(lysc_node, 0, 0, 0x105, 1, "guid", 1, LYS_LEAF, 1, 0, 0, 0);
+ CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "guid", 1, LYS_LEAF, 1, 0, 0, 0);
lysc_node = lysc_node->next;
- CHECK_LYSC_NODE(lysc_node, 0, 0, 0x85, 1, "users", 0, LYS_LIST, 1, 0, 0, 0);
+ CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "users", 0, LYS_LIST, 1, 0, 0, 0);
schema = MODULE_CREATE_YANG("T4", "list user {"
"key \"uid name\";"
@@ -128,14 +128,14 @@
"}");
UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
lysc_leaf = (void *)mod->compiled->data;
- CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, 0x85, 1, "user", 0, \
+ CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "user", 0, \
0, 0, 0, 0, 1, 0xffffffff, 0, 0, 0, 1, 0);
lysc_node = lysc_leaf->child;
- CHECK_LYSC_NODE(lysc_node, 0, 0, 0x105, 1, "uid", 1, LYS_LEAF, 1, 0, 0, 0);
+ CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "uid", 1, LYS_LEAF, 1, 0, 0, 0);
lysc_node = lysc_node->next;
- CHECK_LYSC_NODE(lysc_node, 0, 0, 0x185, 1, "name", 1, LYS_LEAF, 1, 0, 0, 0);
+ CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_UNIQUE | LYS_KEY, 1, "name", 1, LYS_LEAF, 1, 0, 0, 0);
lysc_node = lysc_node->next;
- CHECK_LYSC_NODE(lysc_node, 0, 0, 0x5, 1, "group", 0, LYS_LEAF, 1, 0, 0, 0);
+ CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR, 1, "group", 0, LYS_LEAF, 1, 0, 0, 0);
schema = MODULE_CREATE_YANG("T5", "list rule {"
"key \"id\";"
@@ -148,16 +148,16 @@
"}");
UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
lysc_leaf = (void *)mod->compiled->data;
- CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, 0x85, 1, "rule", 0, \
+ CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "rule", 0, \
0, 0, 0, 0, 1, 0xffffffff, 0, 0, 0, 2, 0);
lysc_node = lysc_leaf->child;
- CHECK_LYSC_NODE(lysc_node, 0, 0, 0x105, 1, "id", 1, LYS_LEAF, 1, 0, 0, 0);
+ CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "id", 1, LYS_LEAF, 1, 0, 0, 0);
lysc_node = lysc_node->next;
- CHECK_LYSC_NODE(lysc_node, 0, 0, 0x85, 1, "name", 1, LYS_LEAF, 1, 0, 0, 0);
+ CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_UNIQUE, 1, "name", 1, LYS_LEAF, 1, 0, 0, 0);
lysc_node = lysc_node->next;
- CHECK_LYSC_NODE(lysc_node, 0, 0, 0x85, 1, "ip", 1, LYS_LEAF, 1, 0, 0, 0);
+ CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_UNIQUE, 1, "ip", 1, LYS_LEAF, 1, 0, 0, 0);
lysc_node = lysc_node->next;
- CHECK_LYSC_NODE(lysc_node, 0, 0, 0x85, 1, "port", 0, LYS_LEAF, 1, 0, 0, 0);
+ CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_UNIQUE, 1, "port", 0, LYS_LEAF, 1, 0, 0, 0);
/* test error */
schema = MODULE_CREATE_YANG("TERR_0", "list user {"
@@ -227,14 +227,14 @@
"}");
UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
lysc_leaf = (void *)mod->compiled->data;
- CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, 0xa86, 1, "user", 0, \
- 0, 0, 0, 0, 1, 0xffffffff, 0, 0, 0, 0, 0);
+ CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, LYS_CONFIG_R | LYS_STATUS_CURR | LYS_ORDBY_USER | LYS_KEYLESS | LYS_SET_CONFIG, \
+ 1, "user", 0, 0, 0, 0, 0, 1, 0xffffffff, 0, 0, 0, 0, 0);
lysc_node = lysc_leaf->child;
- CHECK_LYSC_NODE(lysc_node, 0, 0, 0x6, 1, "uid", 1, LYS_LEAF, 1, 0, 0, 0);
+ CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_R | LYS_STATUS_CURR, 1, "uid", 1, LYS_LEAF, 1, 0, 0, 0);
lysc_node = lysc_node->next;
- CHECK_LYSC_NODE(lysc_node, 0, 0, 0x6, 1, "name", 1, LYS_LEAF, 1, 0, 0, 0);
+ CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_R | LYS_STATUS_CURR, 1, "name", 1, LYS_LEAF, 1, 0, 0, 0);
lysc_node = lysc_node->next;
- CHECK_LYSC_NODE(lysc_node, 0, 0, 0x6, 1, "group", 0, LYS_LEAF, 1, 0, 0, 0);
+ CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_R | LYS_STATUS_CURR, 1, "group", 0, LYS_LEAF, 1, 0, 0, 0);
schema = MODULE_CREATE_YANG("T7", "list user {"
"key uid;"
@@ -246,14 +246,14 @@
"}");
UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
lysc_leaf = (void *)mod->compiled->data;
- CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, 0x45, 1, "user", 0, \
+ CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_USER, 1, "user", 0, \
0, 0, 0, 0, 1, 0xffffffff, 0, 0, 0, 1, 0);
lysc_node = lysc_leaf->child;
- CHECK_LYSC_NODE(lysc_node, 0, 0, 0x105, 1, "uid", 1, LYS_LEAF, 1, 0, 0, 0);
+ CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "uid", 1, LYS_LEAF, 1, 0, 0, 0);
lysc_node = lysc_node->next;
- CHECK_LYSC_NODE(lysc_node, 0, 0, 0x85, 1, "name", 1, LYS_LEAF, 1, 0, 0, 0);
+ CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_UNIQUE, 1, "name", 1, LYS_LEAF, 1, 0, 0, 0);
lysc_node = lysc_node->next;
- CHECK_LYSC_NODE(lysc_node, 0, 0, 0x5, 1, "group", 0, LYS_LEAF, 1, 0, 0, 0);
+ CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR, 1, "group", 0, LYS_LEAF, 1, 0, 0, 0);
schema = MODULE_CREATE_YANG("T8", "list user {"
"key uid;"
@@ -265,14 +265,14 @@
"}");
UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
lysc_leaf = (void *)mod->compiled->data;
- CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, 0x85, 1, "user", 0, \
+ CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "user", 0, \
0, 0, 0, 0, 1, 0xffffffff, 0, 0, 0, 1, 0);
lysc_node = lysc_leaf->child;
- CHECK_LYSC_NODE(lysc_node, 0, 0, 0x105, 1, "uid", 1, LYS_LEAF, 1, 0, 0, 0);
+ CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "uid", 1, LYS_LEAF, 1, 0, 0, 0);
lysc_node = lysc_node->next;
- CHECK_LYSC_NODE(lysc_node, 0, 0, 0x85, 1, "name", 1, LYS_LEAF, 1, 0, 0, 0);
+ CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_UNIQUE, 1, "name", 1, LYS_LEAF, 1, 0, 0, 0);
lysc_node = lysc_node->next;
- CHECK_LYSC_NODE(lysc_node, 0, 0, 0x5, 1, "group", 0, LYS_LEAF, 1, 0, 0, 0);
+ CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR, 1, "group", 0, LYS_LEAF, 1, 0, 0, 0);
schema = MODULE_CREATE_YANG("TERROR0", "list user {"
"key uid;"
@@ -308,14 +308,14 @@
"}");
UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
lysc_leaf = (void *)mod->compiled->data;
- CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, 0x85, 1, "user", 0, \
+ CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "user", 0, \
0, 0, 0, 0, 1, 0xffffffff, 0, 0, 0, 1, 0);
lysc_node = lysc_leaf->child;
- CHECK_LYSC_NODE(lysc_node, 0, 0, 0x105, 1, "uid", 1, LYS_LEAF, 1, 0, 0, 0);
+ CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "uid", 1, LYS_LEAF, 1, 0, 0, 0);
lysc_node = lysc_node->next;
- CHECK_LYSC_NODE(lysc_node, 0, 0, 0x85, 1, "name", 1, LYS_LEAF, 1, 0, 0, 0);
+ CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_UNIQUE, 1, "name", 1, LYS_LEAF, 1, 0, 0, 0);
lysc_node = lysc_node->next;
- CHECK_LYSC_NODE(lysc_node, 0, 0, 0x205, 1, "group", 0, LYS_LEAF, 1, 0, 0, 0);
+ CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_SET_DFLT, 1, "group", 0, LYS_LEAF, 1, 0, 0, 0);
schema = MODULE_CREATE_YANG("T10", "list user {"
"key uid;"
@@ -325,14 +325,14 @@
"}");
UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
lysc_leaf = (void *)mod->compiled->data;
- CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, 0x85, 1, "user", 0, \
+ CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "user", 0, \
0, 0, 0, 0, 1, 0xffffffff, 0, 0, 0, 0, 0);
lysc_node = lysc_leaf->child;
- CHECK_LYSC_NODE(lysc_node, 0, 0, 0x305, 1, "uid", 1, LYS_LEAF, 1, 0, 0, 0);
+ CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY | LYS_SET_DFLT, 1, "uid", 1, LYS_LEAF, 1, 0, 0, 0);
lysc_node = lysc_node->next;
- CHECK_LYSC_NODE(lysc_node, 0, 0, 0x5, 1, "name", 1, LYS_LEAF, 1, 0, 0, 0);
+ CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR, 1, "name", 1, LYS_LEAF, 1, 0, 0, 0);
lysc_node = lysc_node->next;
- CHECK_LYSC_NODE(lysc_node, 0, 0, 0x5, 1, "group", 0, LYS_LEAF, 1, 0, 0, 0);
+ CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR, 1, "group", 0, LYS_LEAF, 1, 0, 0, 0);
schema = MODULE_CREATE_YANG("T11",
"typedef my_type {"
@@ -346,14 +346,14 @@
"}");
UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
lysc_leaf = (void *)mod->compiled->data;
- CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, 0x85, 1, "user", 0, \
+ CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "user", 0, \
0, 0, 0, 0, 1, 0xffffffff, 0, 0, 0, 0, 0);
lysc_node = lysc_leaf->child;
- CHECK_LYSC_NODE(lysc_node, 0, 0, 0x105, 1, "uid", 1, LYS_LEAF, 1, 0, 0, 0);
+ CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "uid", 1, LYS_LEAF, 1, 0, 0, 0);
lysc_node = lysc_node->next;
- CHECK_LYSC_NODE(lysc_node, 0, 0, 0x5, 1, "name", 1, LYS_LEAF, 1, 0, 0, 0);
+ CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR, 1, "name", 1, LYS_LEAF, 1, 0, 0, 0);
lysc_node = lysc_node->next;
- CHECK_LYSC_NODE(lysc_node, 0, 0, 0x5, 1, "group", 0, LYS_LEAF, 1, 0, 0, 0);
+ CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR, 1, "group", 0, LYS_LEAF, 1, 0, 0, 0);
}
@@ -374,14 +374,14 @@
"</list>");
UTEST_ADD_MODULE(schema, LYS_IN_YIN, NULL, &mod);
lysc_leaf = (void *)mod->compiled->data;
- CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, 0x85, 1, "user", 0, \
+ CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "user", 0, \
0, 0, 0, 0, 1, 0xffffffff, 0, 0, 0, 1, 0);
lysc_node = lysc_leaf->child;
- CHECK_LYSC_NODE(lysc_node, 0, 0, 0x105, 1, "uid", 1, LYS_LEAF, 1, 0, 0, 0);
+ CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "uid", 1, LYS_LEAF, 1, 0, 0, 0);
lysc_node = lysc_node->next;
- CHECK_LYSC_NODE(lysc_node, 0, 0, 0x85, 1, "name", 1, LYS_LEAF, 1, 0, 0, 0);
+ CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_UNIQUE, 1, "name", 1, LYS_LEAF, 1, 0, 0, 0);
lysc_node = lysc_node->next;
- CHECK_LYSC_NODE(lysc_node, 0, 0, 0x5, 1, "group", 0, LYS_LEAF, 1, 0, 0, 0);
+ CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR, 1, "group", 0, LYS_LEAF, 1, 0, 0, 0);
schema = MODULE_CREATE_YIN("T00", "<list name=\"user\">"
" <key value=\"u<id\"/>"
@@ -405,12 +405,12 @@
"</list>");
UTEST_ADD_MODULE(schema, LYS_IN_YIN, NULL, &mod);
lysc_leaf = (void *)mod->compiled->data;
- CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, 0x85, 1, "user", 0, \
+ CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "user", 0, \
0, 0, 0, 0, 1, 0xffffffff, 0, 0, 0, 0, 0);
lysc_node = lysc_leaf->child;
- CHECK_LYSC_NODE(lysc_node, 0, 0, 0x105, 1, "uid", 1, LYS_LEAF, 1, 0, 0, 0);
+ CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "uid", 1, LYS_LEAF, 1, 0, 0, 0);
lysc_node = lysc_node->next;
- CHECK_LYSC_NODE(lysc_node, 0, 0, 0x5, 1, "name", 0, LYS_CONTAINER, 1, 0, 0, 0);
+ CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR, 1, "name", 0, LYS_CONTAINER, 1, 0, 0, 0);
schema = MODULE_CREATE_YIN("T2", "<list name=\"grup\">"
"<key value=\"guid\"/>"
@@ -422,12 +422,12 @@
"</list>");
UTEST_ADD_MODULE(schema, LYS_IN_YIN, NULL, &mod);
lysc_leaf = (void *)mod->compiled->data;
- CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, 0x85, 1, "grup", 0, \
+ CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "grup", 0, \
0, 0, 0, 0, 1, 0xffffffff, 0, 0, 0, 0, 0);
lysc_node = lysc_leaf->child;
- CHECK_LYSC_NODE(lysc_node, 0, 0, 0x105, 1, "guid", 1, LYS_LEAF, 1, 0, 0, 0);
+ CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "guid", 1, LYS_LEAF, 1, 0, 0, 0);
lysc_node = lysc_node->next;
- CHECK_LYSC_NODE(lysc_node, 0, 0, 0x85, 1, "users", 0, LYS_LIST, 1, 0, 0, 0);
+ CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "users", 0, LYS_LIST, 1, 0, 0, 0);
/* restriction */
schema = MODULE_CREATE_YIN("T3",
@@ -442,12 +442,12 @@
"</list>");
UTEST_ADD_MODULE(schema, LYS_IN_YIN, NULL, &mod);
lysc_leaf = (void *)mod->compiled->data;
- CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, 0xa5, 1, "grup", 0, \
- 0, 0, 0, 0, 1, 20, 10, 0, 0, 0, 0);
+ CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_MAND_TRUE | LYS_ORDBY_SYSTEM, 1, "grup", \
+ 0, 0, 0, 0, 0, 1, 20, 10, 0, 0, 0, 0);
lysc_node = lysc_leaf->child;
- CHECK_LYSC_NODE(lysc_node, 0, 0, 0x105, 1, "guid", 1, LYS_LEAF, 1, 0, 0, 0);
+ CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "guid", 1, LYS_LEAF, 1, 0, 0, 0);
lysc_node = lysc_node->next;
- CHECK_LYSC_NODE(lysc_node, 0, 0, 0x85, 1, "users", 0, LYS_LIST, 1, 0, 0, 0);
+ CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "users", 0, LYS_LIST, 1, 0, 0, 0);
schema = MODULE_CREATE_YIN("T4",
"<list name=\"user\">"
@@ -459,14 +459,14 @@
"</list>");
UTEST_ADD_MODULE(schema, LYS_IN_YIN, NULL, &mod);
lysc_leaf = (void *)mod->compiled->data;
- CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, 0x85, 1, "user", 0, \
+ CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "user", 0, \
0, 0, 0, 0, 1, 0xffffffff, 0, 0, 0, 1, 0);
lysc_node = lysc_leaf->child;
- CHECK_LYSC_NODE(lysc_node, 0, 0, 0x105, 1, "uid", 1, LYS_LEAF, 1, 0, 0, 0);
+ CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "uid", 1, LYS_LEAF, 1, 0, 0, 0);
lysc_node = lysc_node->next;
- CHECK_LYSC_NODE(lysc_node, 0, 0, 0x185, 1, "name", 1, LYS_LEAF, 1, 0, 0, 0);
+ CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_UNIQUE | LYS_KEY, 1, "name", 1, LYS_LEAF, 1, 0, 0, 0);
lysc_node = lysc_node->next;
- CHECK_LYSC_NODE(lysc_node, 0, 0, 0x5, 1, "group", 0, LYS_LEAF, 1, 0, 0, 0);
+ CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR, 1, "group", 0, LYS_LEAF, 1, 0, 0, 0);
schema = MODULE_CREATE_YIN("T5",
"<list name=\"rule\">"
@@ -480,16 +480,16 @@
"</list>");
UTEST_ADD_MODULE(schema, LYS_IN_YIN, NULL, &mod);
lysc_leaf = (void *)mod->compiled->data;
- CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, 0x85, 1, "rule", 0, \
+ CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "rule", 0, \
0, 0, 0, 0, 1, 0xffffffff, 0, 0, 0, 2, 0);
lysc_node = lysc_leaf->child;
- CHECK_LYSC_NODE(lysc_node, 0, 0, 0x105, 1, "id", 1, LYS_LEAF, 1, 0, 0, 0);
+ CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "id", 1, LYS_LEAF, 1, 0, 0, 0);
lysc_node = lysc_node->next;
- CHECK_LYSC_NODE(lysc_node, 0, 0, 0x85, 1, "name", 1, LYS_LEAF, 1, 0, 0, 0);
+ CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_UNIQUE, 1, "name", 1, LYS_LEAF, 1, 0, 0, 0);
lysc_node = lysc_node->next;
- CHECK_LYSC_NODE(lysc_node, 0, 0, 0x85, 1, "ip", 1, LYS_LEAF, 1, 0, 0, 0);
+ CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_UNIQUE, 1, "ip", 1, LYS_LEAF, 1, 0, 0, 0);
lysc_node = lysc_node->next;
- CHECK_LYSC_NODE(lysc_node, 0, 0, 0x85, 1, "port", 0, LYS_LEAF, 1, 0, 0, 0);
+ CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_UNIQUE, 1, "port", 0, LYS_LEAF, 1, 0, 0, 0);
/* test error */
schema = MODULE_CREATE_YIN("TERR_0",
@@ -563,14 +563,14 @@
"</list>");
UTEST_ADD_MODULE(schema, LYS_IN_YIN, NULL, &mod);
lysc_leaf = (void *)mod->compiled->data;
- CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, 0xa86, 1, "user", 0, \
- 0, 0, 0, 0, 1, 0xffffffff, 0, 0, 0, 0, 0);
+ CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, LYS_CONFIG_R | LYS_STATUS_CURR | LYS_ORDBY_USER | LYS_KEYLESS | LYS_SET_CONFIG, \
+ 1, "user", 0, 0, 0, 0, 0, 1, 0xffffffff, 0, 0, 0, 0, 0);
lysc_node = lysc_leaf->child;
- CHECK_LYSC_NODE(lysc_node, 0, 0, 0x6, 1, "uid", 1, LYS_LEAF, 1, 0, 0, 0);
+ CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_R | LYS_STATUS_CURR, 1, "uid", 1, LYS_LEAF, 1, 0, 0, 0);
lysc_node = lysc_node->next;
- CHECK_LYSC_NODE(lysc_node, 0, 0, 0x6, 1, "name", 1, LYS_LEAF, 1, 0, 0, 0);
+ CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_R | LYS_STATUS_CURR, 1, "name", 1, LYS_LEAF, 1, 0, 0, 0);
lysc_node = lysc_node->next;
- CHECK_LYSC_NODE(lysc_node, 0, 0, 0x6, 1, "group", 0, LYS_LEAF, 1, 0, 0, 0);
+ CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_R | LYS_STATUS_CURR, 1, "group", 0, LYS_LEAF, 1, 0, 0, 0);
schema = MODULE_CREATE_YIN("T7",
"<list name=\"user\">"
@@ -583,14 +583,14 @@
"</list>");
UTEST_ADD_MODULE(schema, LYS_IN_YIN, NULL, &mod);
lysc_leaf = (void *)mod->compiled->data;
- CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, 0x45, 1, "user", 0, \
+ CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_USER, 1, "user", 0, \
0, 0, 0, 0, 1, 0xffffffff, 0, 0, 0, 1, 0);
lysc_node = lysc_leaf->child;
- CHECK_LYSC_NODE(lysc_node, 0, 0, 0x105, 1, "uid", 1, LYS_LEAF, 1, 0, 0, 0);
+ CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "uid", 1, LYS_LEAF, 1, 0, 0, 0);
lysc_node = lysc_node->next;
- CHECK_LYSC_NODE(lysc_node, 0, 0, 0x85, 1, "name", 1, LYS_LEAF, 1, 0, 0, 0);
+ CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_UNIQUE, 1, "name", 1, LYS_LEAF, 1, 0, 0, 0);
lysc_node = lysc_node->next;
- CHECK_LYSC_NODE(lysc_node, 0, 0, 0x5, 1, "group", 0, LYS_LEAF, 1, 0, 0, 0);
+ CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR, 1, "group", 0, LYS_LEAF, 1, 0, 0, 0);
schema = MODULE_CREATE_YIN("T8",
"<list name=\"user\">"
@@ -603,14 +603,14 @@
"</list>");
UTEST_ADD_MODULE(schema, LYS_IN_YIN, NULL, &mod);
lysc_leaf = (void *)mod->compiled->data;
- CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, 0x85, 1, "user", 0, \
+ CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "user", 0, \
0, 0, 0, 0, 1, 0xffffffff, 0, 0, 0, 1, 0);
lysc_node = lysc_leaf->child;
- CHECK_LYSC_NODE(lysc_node, 0, 0, 0x105, 1, "uid", 1, LYS_LEAF, 1, 0, 0, 0);
+ CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "uid", 1, LYS_LEAF, 1, 0, 0, 0);
lysc_node = lysc_node->next;
- CHECK_LYSC_NODE(lysc_node, 0, 0, 0x85, 1, "name", 1, LYS_LEAF, 1, 0, 0, 0);
+ CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_UNIQUE, 1, "name", 1, LYS_LEAF, 1, 0, 0, 0);
lysc_node = lysc_node->next;
- CHECK_LYSC_NODE(lysc_node, 0, 0, 0x5, 1, "group", 0, LYS_LEAF, 1, 0, 0, 0);
+ CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR, 1, "group", 0, LYS_LEAF, 1, 0, 0, 0);
schema = MODULE_CREATE_YIN("TERROR0",
"<list name=\"user\">"
@@ -636,14 +636,14 @@
"</list>");
UTEST_ADD_MODULE(schema, LYS_IN_YIN, NULL, &mod);
lysc_leaf = (void *)mod->compiled->data;
- CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, 0x85, 1, "user", 0, \
+ CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "user", 0, \
0, 0, 0, 0, 1, 0xffffffff, 0, 0, 0, 1, 0);
lysc_node = lysc_leaf->child;
- CHECK_LYSC_NODE(lysc_node, 0, 0, 0x105, 1, "uid", 1, LYS_LEAF, 1, 0, 0, 0);
+ CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "uid", 1, LYS_LEAF, 1, 0, 0, 0);
lysc_node = lysc_node->next;
- CHECK_LYSC_NODE(lysc_node, 0, 0, 0x85, 1, "name", 1, LYS_LEAF, 1, 0, 0, 0);
+ CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_UNIQUE, 1, "name", 1, LYS_LEAF, 1, 0, 0, 0);
lysc_node = lysc_node->next;
- CHECK_LYSC_NODE(lysc_node, 0, 0, 0x205, 1, "group", 0, LYS_LEAF, 1, 0, 0, 0);
+ CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_SET_DFLT, 1, "group", 0, LYS_LEAF, 1, 0, 0, 0);
}
diff --git a/tests/utests/schema/test_tree_schema_compile.c b/tests/utests/schema/test_tree_schema_compile.c
index ce295b5..a7696b7 100644
--- a/tests/utests/schema/test_tree_schema_compile.c
+++ b/tests/utests/schema/test_tree_schema_compile.c
@@ -261,7 +261,7 @@
assert_int_equal(0, dynamic);
assert_string_equal("1", dflt = ll->dflts[1]->realtype->plugin->print(ll->dflts[1], LY_PREF_SCHEMA, NULL, &dynamic));
assert_int_equal(0, dynamic);
- assert_int_equal(LYS_CONFIG_R | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM | LYS_SET_DFLT | LYS_SET_CONFIG, ll->flags);
+ assert_int_equal(LYS_CONFIG_R | LYS_STATUS_CURR | LYS_ORDBY_USER | LYS_SET_DFLT | LYS_SET_CONFIG, ll->flags);
assert_non_null((ll = (struct lysc_node_leaflist *)mod->compiled->data->next));
assert_non_null(ll->dflts);
assert_int_equal(6, ll->type->refcount); /* 3x type's reference, 3x default value's reference */
@@ -277,7 +277,7 @@
CHECK_LOG_CTX("The ordered-by statement is ignored in lists representing state data (/d:ll).", NULL);
assert_non_null(mod->compiled);
assert_non_null((ll = (struct lysc_node_leaflist *)mod->compiled->data));
- assert_int_equal(LYS_CONFIG_R | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM | LYS_SET_CONFIG, ll->flags);
+ assert_int_equal(LYS_CONFIG_R | LYS_STATUS_CURR | LYS_ORDBY_USER | LYS_SET_CONFIG, ll->flags);
UTEST_LOG_CLEAN;
assert_int_equal(LY_SUCCESS, lys_parse_mem(UTEST_LYCTX, "module e {yang-version 1.1;namespace urn:e;prefix e;"
@@ -352,7 +352,7 @@
assert_non_null(list);
assert_non_null(list->child);
assert_false(list->child->flags & LYS_KEY);
- assert_int_equal(LYS_CONFIG_R | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM | LYS_SET_CONFIG | LYS_KEYLESS, list->flags);
+ assert_int_equal(LYS_CONFIG_R | LYS_STATUS_CURR | LYS_ORDBY_USER | LYS_SET_CONFIG | LYS_KEYLESS, list->flags);
assert_int_equal(LY_SUCCESS, lys_parse_mem(UTEST_LYCTX, "module b {namespace urn:b;prefix b;"
"list l {key a; unique \"a c/b:b\"; unique \"c/e d\";"
diff --git a/tools/lint/tests/expect/list.exp b/tools/lint/tests/expect/list.exp
index 093ac73..92fea12 100755
--- a/tools/lint/tests/expect/list.exp
+++ b/tools/lint/tests/expect/list.exp
@@ -9,7 +9,7 @@
"list\r
List of the loaded models:\r
i ietf-yang-metadata@2016-08-05\r
- I yang@2020-06-17\r
+ I yang@2021-04-07\r
i ietf-inet-types@2013-07-15\r
i ietf-yang-types@2013-07-15\r
I ietf-datastores@2018-02-14\r
diff --git a/tools/lint/tests/shunit2/list.sh b/tools/lint/tests/shunit2/list.sh
index d07b682..fe6cf2a 100755
--- a/tools/lint/tests/shunit2/list.sh
+++ b/tools/lint/tests/shunit2/list.sh
@@ -2,7 +2,7 @@
LIST_BASE="List of the loaded models:
i ietf-yang-metadata@2016-08-05
- I yang@2020-06-17
+ I yang@2021-04-07
i ietf-inet-types@2013-07-15
i ietf-yang-types@2013-07-15"
@@ -14,7 +14,7 @@
testListAllImplemented() {
LIST_BASE_ALLIMPLEMENTED="List of the loaded models:
I ietf-yang-metadata@2016-08-05
- I yang@2020-06-17
+ I yang@2021-04-07
I ietf-inet-types@2013-07-15
I ietf-yang-types@2013-07-15"
output=`${YANGLINT} -lii`