diff --git a/CMakeLists.txt b/CMakeLists.txt index 7414e1f70..d0dc717e9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -157,6 +157,8 @@ set(libsrc src/plugins_exts/yangdata.c src/plugins_exts/schema_mount.c src/plugins_exts/structure.c + src/plugins_exts/yang_semver.c + src/plugins_exts/yang_revisions.c src/xml.c src/xpath.c src/validation.c diff --git a/models/ietf-yang-revisions@2025-01-28.h b/models/ietf-yang-revisions@2025-01-28.h new file mode 100644 index 000000000..7fbd7343f --- /dev/null +++ b/models/ietf-yang-revisions@2025-01-28.h @@ -0,0 +1,457 @@ +unsigned char ietf_yang_revisions_2025_01_28_yang[] = { + 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x20, 0x69, 0x65, 0x74, 0x66, 0x2d, + 0x79, 0x61, 0x6e, 0x67, 0x2d, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, + 0x6e, 0x73, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x79, 0x61, 0x6e, 0x67, 0x2d, + 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x31, 0x2e, 0x31, 0x3b, + 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, 0x69, 0x65, 0x74, 0x66, 0x2d, 0x79, + 0x61, 0x6e, 0x67, 0x2d, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, + 0x73, 0x22, 0x3b, 0x0a, 0x20, 0x20, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, + 0x20, 0x72, 0x65, 0x76, 0x3b, 0x0a, 0x0a, 0x20, 0x20, 0x69, 0x6d, 0x70, + 0x6f, 0x72, 0x74, 0x20, 0x69, 0x65, 0x74, 0x66, 0x2d, 0x79, 0x61, 0x6e, + 0x67, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x73, 0x20, 0x7b, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x20, 0x79, 0x61, 0x6e, + 0x67, 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, 0x59, 0x59, 0x59, 0x59, 0x2d, 0x64, 0x72, 0x61, + 0x66, 0x74, 0x2d, 0x69, 0x65, 0x74, 0x66, 0x2d, 0x6e, 0x65, 0x74, 0x6d, + 0x6f, 0x64, 0x2d, 0x72, 0x66, 0x63, 0x36, 0x39, 0x39, 0x31, 0x2d, 0x62, + 0x69, 0x73, 0x3a, 0x20, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x20, 0x59, + 0x41, 0x4e, 0x47, 0x20, 0x44, 0x61, 0x74, 0x61, 0x20, 0x54, 0x79, 0x70, + 0x65, 0x73, 0x22, 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, 0x49, 0x45, 0x54, 0x46, 0x20, 0x4e, + 0x45, 0x54, 0x4d, 0x4f, 0x44, 0x20, 0x28, 0x4e, 0x65, 0x74, 0x77, 0x6f, + 0x72, 0x6b, 0x20, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x69, 0x6e, 0x67, 0x29, + 0x20, 0x57, 0x6f, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x20, 0x47, 0x72, 0x6f, + 0x75, 0x70, 0x22, 0x3b, 0x0a, 0x20, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, + 0x63, 0x74, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, 0x57, 0x47, 0x20, 0x57, + 0x65, 0x62, 0x3a, 0x20, 0x20, 0x20, 0x3c, 0x68, 0x74, 0x74, 0x70, 0x73, + 0x3a, 0x2f, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x74, 0x72, 0x61, 0x63, 0x6b, + 0x65, 0x72, 0x2e, 0x69, 0x65, 0x74, 0x66, 0x2e, 0x6f, 0x72, 0x67, 0x2f, + 0x77, 0x67, 0x2f, 0x6e, 0x65, 0x74, 0x6d, 0x6f, 0x64, 0x2f, 0x3e, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x57, 0x47, 0x20, 0x4c, 0x69, 0x73, 0x74, + 0x3a, 0x20, 0x20, 0x3c, 0x6d, 0x61, 0x69, 0x6c, 0x74, 0x6f, 0x3a, 0x6e, + 0x65, 0x74, 0x6d, 0x6f, 0x64, 0x40, 0x69, 0x65, 0x74, 0x66, 0x2e, 0x6f, + 0x72, 0x67, 0x3e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x41, 0x75, + 0x74, 0x68, 0x6f, 0x72, 0x3a, 0x20, 0x20, 0x20, 0x4a, 0x6f, 0x65, 0x20, + 0x43, 0x6c, 0x61, 0x72, 0x6b, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x6d, 0x61, + 0x69, 0x6c, 0x74, 0x6f, 0x3a, 0x6a, 0x63, 0x6c, 0x61, 0x72, 0x6b, 0x65, + 0x40, 0x63, 0x69, 0x73, 0x63, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x3e, 0x0a, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, + 0x3a, 0x20, 0x20, 0x20, 0x52, 0x65, 0x73, 0x68, 0x61, 0x64, 0x20, 0x52, + 0x61, 0x68, 0x6d, 0x61, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x6d, 0x61, 0x69, + 0x6c, 0x74, 0x6f, 0x3a, 0x72, 0x65, 0x73, 0x68, 0x61, 0x64, 0x40, 0x79, + 0x61, 0x68, 0x6f, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x3e, 0x0a, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x3a, 0x20, + 0x20, 0x20, 0x52, 0x6f, 0x62, 0x65, 0x72, 0x74, 0x20, 0x57, 0x69, 0x6c, + 0x74, 0x6f, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x6d, 0x61, 0x69, 0x6c, 0x74, + 0x6f, 0x3a, 0x72, 0x77, 0x69, 0x6c, 0x74, 0x6f, 0x6e, 0x40, 0x63, 0x69, + 0x73, 0x63, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x3e, 0x0a, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x3a, 0x20, 0x20, + 0x20, 0x42, 0x61, 0x6c, 0x61, 0x7a, 0x73, 0x20, 0x4c, 0x65, 0x6e, 0x67, + 0x79, 0x65, 0x6c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x6d, 0x61, 0x69, 0x6c, 0x74, + 0x6f, 0x3a, 0x62, 0x61, 0x6c, 0x61, 0x7a, 0x73, 0x2e, 0x6c, 0x65, 0x6e, + 0x67, 0x79, 0x65, 0x6c, 0x40, 0x65, 0x72, 0x69, 0x63, 0x73, 0x73, 0x6f, + 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x3e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x3a, 0x20, 0x20, 0x20, 0x4a, + 0x61, 0x73, 0x6f, 0x6e, 0x20, 0x53, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x3c, 0x6d, 0x61, 0x69, 0x6c, 0x74, 0x6f, 0x3a, 0x6a, 0x61, + 0x73, 0x6f, 0x6e, 0x2e, 0x73, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x40, 0x6e, + 0x6f, 0x6b, 0x69, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x3e, 0x22, 0x3b, 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, + 0x59, 0x41, 0x4e, 0x47, 0x20, 0x31, 0x2e, 0x31, 0x20, 0x6d, 0x6f, 0x64, + 0x75, 0x6c, 0x65, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x73, + 0x20, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x20, 0x61, 0x6e, 0x64, 0x20, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, + 0x6f, 0x6e, 0x73, 0x20, 0x74, 0x6f, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x20, 0x75, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x64, 0x20, 0x59, 0x41, 0x4e, 0x47, 0x20, 0x72, 0x65, 0x76, + 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x69, + 0x6e, 0x67, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x43, 0x6f, + 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x28, 0x63, 0x29, 0x20, + 0x32, 0x30, 0x32, 0x34, 0x20, 0x49, 0x45, 0x54, 0x46, 0x20, 0x54, 0x72, + 0x75, 0x73, 0x74, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, + 0x70, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x73, 0x20, 0x69, 0x64, 0x65, 0x6e, + 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x20, 0x61, 0x73, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x73, 0x20, 0x6f, + 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x2e, 0x20, + 0x20, 0x41, 0x6c, 0x6c, 0x20, 0x72, 0x69, 0x67, 0x68, 0x74, 0x73, 0x20, + 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x2e, 0x0a, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x52, 0x65, 0x64, 0x69, 0x73, 0x74, 0x72, 0x69, + 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x75, + 0x73, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x20, 0x61, 0x6e, 0x64, 0x20, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x20, + 0x66, 0x6f, 0x72, 0x6d, 0x73, 0x2c, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, + 0x6f, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x77, 0x69, 0x74, 0x68, + 0x6f, 0x75, 0x74, 0x20, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x69, 0x73, 0x20, 0x70, 0x65, 0x72, + 0x6d, 0x69, 0x74, 0x74, 0x65, 0x64, 0x20, 0x70, 0x75, 0x72, 0x73, 0x75, + 0x61, 0x6e, 0x74, 0x20, 0x74, 0x6f, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, + 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x20, 0x74, 0x6f, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, 0x69, 0x63, 0x65, + 0x6e, 0x73, 0x65, 0x20, 0x74, 0x65, 0x72, 0x6d, 0x73, 0x20, 0x63, 0x6f, + 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x2c, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x52, 0x65, 0x76, 0x69, 0x73, 0x65, 0x64, 0x20, + 0x42, 0x53, 0x44, 0x20, 0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x20, + 0x73, 0x65, 0x74, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6f, 0x72, + 0x74, 0x68, 0x20, 0x69, 0x6e, 0x20, 0x53, 0x65, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x34, 0x2e, 0x63, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x49, 0x45, 0x54, 0x46, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x27, + 0x73, 0x20, 0x4c, 0x65, 0x67, 0x61, 0x6c, 0x20, 0x50, 0x72, 0x6f, 0x76, + 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x6f, 0x20, + 0x49, 0x45, 0x54, 0x46, 0x20, 0x44, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, + 0x74, 0x73, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x28, 0x68, 0x74, 0x74, + 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x74, 0x72, 0x75, 0x73, 0x74, 0x65, 0x65, + 0x2e, 0x69, 0x65, 0x74, 0x66, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x6c, 0x69, + 0x63, 0x65, 0x6e, 0x73, 0x65, 0x2d, 0x69, 0x6e, 0x66, 0x6f, 0x29, 0x2e, + 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x54, 0x68, 0x69, 0x73, 0x20, + 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x74, + 0x68, 0x69, 0x73, 0x20, 0x59, 0x41, 0x4e, 0x47, 0x20, 0x6d, 0x6f, 0x64, + 0x75, 0x6c, 0x65, 0x20, 0x69, 0x73, 0x20, 0x70, 0x61, 0x72, 0x74, 0x20, + 0x6f, 0x66, 0x20, 0x52, 0x46, 0x43, 0x20, 0x58, 0x58, 0x58, 0x58, 0x3b, + 0x20, 0x73, 0x65, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x52, 0x46, 0x43, 0x20, 0x69, 0x74, 0x73, 0x65, 0x6c, 0x66, + 0x20, 0x66, 0x6f, 0x72, 0x20, 0x66, 0x75, 0x6c, 0x6c, 0x20, 0x6c, 0x65, + 0x67, 0x61, 0x6c, 0x20, 0x6e, 0x6f, 0x74, 0x69, 0x63, 0x65, 0x73, 0x2e, + 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x54, 0x68, 0x65, 0x20, 0x6b, + 0x65, 0x79, 0x20, 0x77, 0x6f, 0x72, 0x64, 0x73, 0x20, 0x27, 0x4d, 0x55, + 0x53, 0x54, 0x27, 0x2c, 0x20, 0x27, 0x4d, 0x55, 0x53, 0x54, 0x20, 0x4e, + 0x4f, 0x54, 0x27, 0x2c, 0x20, 0x27, 0x52, 0x45, 0x51, 0x55, 0x49, 0x52, + 0x45, 0x44, 0x27, 0x2c, 0x20, 0x27, 0x53, 0x48, 0x41, 0x4c, 0x4c, 0x27, + 0x2c, 0x20, 0x27, 0x53, 0x48, 0x41, 0x4c, 0x4c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x4e, 0x4f, 0x54, 0x27, 0x2c, 0x20, 0x27, 0x53, 0x48, 0x4f, + 0x55, 0x4c, 0x44, 0x27, 0x2c, 0x20, 0x27, 0x53, 0x48, 0x4f, 0x55, 0x4c, + 0x44, 0x20, 0x4e, 0x4f, 0x54, 0x27, 0x2c, 0x20, 0x27, 0x52, 0x45, 0x43, + 0x4f, 0x4d, 0x4d, 0x45, 0x4e, 0x44, 0x45, 0x44, 0x27, 0x2c, 0x20, 0x27, + 0x4e, 0x4f, 0x54, 0x20, 0x52, 0x45, 0x43, 0x4f, 0x4d, 0x4d, 0x45, 0x4e, + 0x44, 0x45, 0x44, 0x27, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x27, + 0x4d, 0x41, 0x59, 0x27, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x27, 0x4f, + 0x50, 0x54, 0x49, 0x4f, 0x4e, 0x41, 0x4c, 0x27, 0x20, 0x69, 0x6e, 0x20, + 0x74, 0x68, 0x69, 0x73, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, + 0x74, 0x20, 0x61, 0x72, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x62, 0x65, 0x20, + 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x20, + 0x61, 0x73, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x65, 0x73, 0x63, + 0x72, 0x69, 0x62, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x42, 0x43, 0x50, + 0x20, 0x31, 0x34, 0x20, 0x28, 0x52, 0x46, 0x43, 0x20, 0x32, 0x31, 0x31, + 0x39, 0x29, 0x20, 0x28, 0x52, 0x46, 0x43, 0x20, 0x38, 0x31, 0x37, 0x34, + 0x29, 0x20, 0x77, 0x68, 0x65, 0x6e, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, + 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x77, 0x68, 0x65, 0x6e, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x74, 0x68, 0x65, 0x79, 0x20, 0x61, 0x70, 0x70, + 0x65, 0x61, 0x72, 0x20, 0x69, 0x6e, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x63, + 0x61, 0x70, 0x69, 0x74, 0x61, 0x6c, 0x73, 0x2c, 0x20, 0x61, 0x73, 0x20, + 0x73, 0x68, 0x6f, 0x77, 0x6e, 0x20, 0x68, 0x65, 0x72, 0x65, 0x2e, 0x22, + 0x3b, 0x0a, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x52, 0x46, 0x43, 0x20, 0x45, + 0x64, 0x2e, 0x3a, 0x20, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x64, 0x61, 0x74, 0x65, 0x20, 0x62, 0x65, 0x6c, 0x6f, + 0x77, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x64, + 0x61, 0x74, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x52, 0x46, 0x43, 0x20, 0x70, + 0x75, 0x62, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x20, + 0x20, 0x2f, 0x2f, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x72, 0x65, 0x6d, 0x6f, + 0x76, 0x65, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x6e, 0x6f, 0x74, 0x65, + 0x2e, 0x0a, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x52, 0x46, 0x43, 0x20, 0x45, + 0x64, 0x2e, 0x3a, 0x20, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x20, + 0x58, 0x58, 0x58, 0x58, 0x20, 0x28, 0x69, 0x6e, 0x63, 0x20, 0x61, 0x62, + 0x6f, 0x76, 0x65, 0x29, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x61, 0x63, + 0x74, 0x75, 0x61, 0x6c, 0x20, 0x52, 0x46, 0x43, 0x20, 0x6e, 0x75, 0x6d, + 0x62, 0x65, 0x72, 0x20, 0x61, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x2f, 0x2f, + 0x20, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x20, 0x74, 0x68, 0x69, 0x73, + 0x20, 0x6e, 0x6f, 0x74, 0x65, 0x2e, 0x0a, 0x20, 0x20, 0x2f, 0x2f, 0x20, + 0x52, 0x46, 0x43, 0x20, 0x45, 0x64, 0x2e, 0x3a, 0x20, 0x72, 0x65, 0x70, + 0x6c, 0x61, 0x63, 0x65, 0x20, 0x59, 0x59, 0x59, 0x59, 0x2d, 0x64, 0x72, + 0x61, 0x66, 0x74, 0x2d, 0x69, 0x65, 0x74, 0x66, 0x2d, 0x6e, 0x65, 0x74, + 0x6d, 0x6f, 0x64, 0x2d, 0x72, 0x66, 0x63, 0x36, 0x39, 0x39, 0x31, 0x2d, + 0x62, 0x69, 0x73, 0x20, 0x28, 0x69, 0x6e, 0x63, 0x20, 0x61, 0x62, 0x6f, + 0x76, 0x65, 0x29, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x61, 0x63, 0x74, + 0x75, 0x61, 0x6c, 0x20, 0x52, 0x46, 0x43, 0x20, 0x6e, 0x75, 0x6d, 0x62, + 0x65, 0x72, 0x20, 0x61, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x2f, 0x2f, 0x20, + 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, + 0x6e, 0x6f, 0x74, 0x65, 0x2e, 0x0a, 0x20, 0x20, 0x0a, 0x20, 0x20, 0x72, + 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x32, 0x30, 0x32, 0x35, + 0x2d, 0x30, 0x31, 0x2d, 0x32, 0x38, 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, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 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, 0x58, 0x58, 0x58, 0x58, 0x3a, 0x20, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x64, 0x20, 0x59, 0x41, 0x4e, 0x47, 0x20, 0x4d, + 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x20, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, + 0x6f, 0x6e, 0x20, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x69, 0x6e, 0x67, 0x22, + 0x3b, 0x0a, 0x20, 0x20, 0x7d, 0x0a, 0x0a, 0x20, 0x20, 0x74, 0x79, 0x70, + 0x65, 0x64, 0x65, 0x66, 0x20, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, + 0x6e, 0x2d, 0x64, 0x61, 0x74, 0x65, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x79, 0x61, 0x6e, 0x67, 0x3a, 0x64, + 0x61, 0x74, 0x65, 0x2d, 0x6e, 0x6f, 0x2d, 0x7a, 0x6f, 0x6e, 0x65, 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, + 0x41, 0x20, 0x64, 0x61, 0x74, 0x65, 0x20, 0x61, 0x73, 0x73, 0x6f, 0x63, + 0x69, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x61, + 0x20, 0x59, 0x41, 0x4e, 0x47, 0x20, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, + 0x6f, 0x6e, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x20, 0x64, 0x61, 0x74, 0x65, + 0x73, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x74, 0x65, 0x64, 0x20, + 0x61, 0x73, 0x20, 0x59, 0x59, 0x59, 0x59, 0x2d, 0x4d, 0x4d, 0x2d, 0x44, + 0x44, 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, 0x65, 0x78, 0x74, + 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x6e, 0x6f, 0x6e, 0x2d, 0x62, + 0x61, 0x63, 0x6b, 0x77, 0x61, 0x72, 0x64, 0x73, 0x2d, 0x63, 0x6f, 0x6d, + 0x70, 0x61, 0x74, 0x69, 0x62, 0x6c, 0x65, 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, 0x54, 0x68, 0x69, + 0x73, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x20, + 0x69, 0x73, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x69, + 0x6e, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x59, 0x41, 0x4e, 0x47, + 0x20, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x20, 0x72, 0x65, 0x76, 0x69, + 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, + 0x6e, 0x20, 0x6e, 0x6f, 0x6e, 0x2d, 0x62, 0x61, 0x63, 0x6b, 0x77, 0x61, + 0x72, 0x64, 0x73, 0x2d, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x74, 0x69, 0x62, + 0x6c, 0x65, 0x20, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x2e, 0x0a, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x54, 0x68, 0x65, 0x20, + 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x4d, 0x55, + 0x53, 0x54, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x62, 0x65, 0x20, 0x61, + 0x20, 0x73, 0x75, 0x62, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, + 0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x27, 0x72, 0x65, + 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x27, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, + 0x2e, 0x20, 0x20, 0x5a, 0x65, 0x72, 0x6f, 0x20, 0x6f, 0x72, 0x20, 0x6f, + 0x6e, 0x65, 0x20, 0x27, 0x6e, 0x6f, 0x6e, 0x2d, 0x62, 0x61, 0x63, 0x6b, + 0x77, 0x61, 0x72, 0x64, 0x73, 0x2d, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x74, + 0x69, 0x62, 0x6c, 0x65, 0x27, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, + 0x65, 0x6e, 0x74, 0x73, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x70, 0x65, 0x72, 0x20, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x20, 0x73, + 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x69, 0x73, 0x20, + 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x2e, 0x20, 0x20, 0x4e, 0x6f, + 0x20, 0x73, 0x75, 0x62, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, + 0x74, 0x73, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x69, 0x73, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, 0x78, 0x74, 0x65, 0x6e, + 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x68, 0x61, 0x76, 0x65, 0x20, 0x62, 0x65, + 0x65, 0x6e, 0x20, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x69, + 0x7a, 0x65, 0x64, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x49, 0x66, 0x20, 0x61, 0x20, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, + 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x61, 0x20, 0x59, 0x41, 0x4e, 0x47, + 0x20, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x20, 0x63, 0x6f, 0x6e, 0x74, + 0x61, 0x69, 0x6e, 0x73, 0x20, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, + 0x2c, 0x20, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x20, 0x74, + 0x6f, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x70, 0x72, 0x65, 0x63, 0x65, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x72, + 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x6e, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x20, + 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x2c, 0x20, 0x74, 0x68, 0x61, + 0x74, 0x20, 0x64, 0x6f, 0x20, 0x6e, 0x6f, 0x74, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x20, + 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x77, + 0x61, 0x72, 0x64, 0x73, 0x2d, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x74, 0x69, + 0x62, 0x6c, 0x65, 0x20, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x20, 0x75, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x20, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x65, 0x66, 0x69, 0x6e, + 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x52, 0x46, 0x43, 0x2d, 0x58, 0x58, + 0x58, 0x58, 0x2c, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x27, 0x6e, 0x6f, 0x6e, 0x2d, 0x62, 0x61, 0x63, 0x6b, 0x77, 0x61, + 0x72, 0x64, 0x73, 0x2d, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x74, 0x69, 0x62, + 0x6c, 0x65, 0x27, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, + 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x4d, 0x55, 0x53, + 0x54, 0x20, 0x62, 0x65, 0x20, 0x61, 0x64, 0x64, 0x65, 0x64, 0x20, 0x61, + 0x73, 0x20, 0x61, 0x20, 0x73, 0x75, 0x62, 0x73, 0x74, 0x61, 0x74, 0x65, + 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, + 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, + 0x74, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x43, + 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x65, 0x6c, 0x79, 0x2c, 0x20, 0x69, + 0x66, 0x20, 0x61, 0x20, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, + 0x20, 0x64, 0x6f, 0x65, 0x73, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x63, 0x6f, + 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x20, 0x61, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x27, 0x6e, 0x6f, 0x6e, 0x2d, 0x62, 0x61, 0x63, 0x6b, + 0x77, 0x61, 0x72, 0x64, 0x73, 0x2d, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x74, + 0x69, 0x62, 0x6c, 0x65, 0x27, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, + 0x65, 0x6e, 0x74, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x61, 0x6c, 0x6c, + 0x20, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x76, + 0x65, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x72, 0x65, + 0x63, 0x65, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x72, 0x65, 0x76, 0x69, 0x73, + 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, + 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x68, 0x69, 0x73, 0x74, + 0x6f, 0x72, 0x79, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x4d, 0x55, 0x53, 0x54, 0x20, 0x62, 0x65, 0x20, 0x62, 0x61, 0x63, 0x6b, + 0x77, 0x61, 0x72, 0x64, 0x73, 0x2d, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x74, + 0x69, 0x62, 0x6c, 0x65, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x41, 0x20, 0x6e, 0x65, 0x77, 0x20, 0x6d, 0x6f, 0x64, 0x75, + 0x6c, 0x65, 0x20, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x20, + 0x74, 0x68, 0x61, 0x74, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x63, 0x6f, + 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x73, 0x20, 0x63, 0x68, 0x61, 0x6e, 0x67, + 0x65, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x61, 0x72, 0x65, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x77, + 0x61, 0x72, 0x64, 0x73, 0x2d, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x74, 0x69, + 0x62, 0x6c, 0x65, 0x20, 0x53, 0x48, 0x4f, 0x55, 0x4c, 0x44, 0x20, 0x4e, + 0x4f, 0x54, 0x20, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x20, 0x74, + 0x68, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x27, 0x6e, + 0x6f, 0x6e, 0x2d, 0x62, 0x61, 0x63, 0x6b, 0x77, 0x61, 0x72, 0x64, 0x73, + 0x2d, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x74, 0x69, 0x62, 0x6c, 0x65, 0x27, + 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x20, + 0x20, 0x41, 0x6e, 0x20, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x20, + 0x6f, 0x66, 0x20, 0x77, 0x68, 0x65, 0x6e, 0x20, 0x61, 0x6e, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, + 0x20, 0x6d, 0x69, 0x67, 0x68, 0x74, 0x20, 0x61, 0x64, 0x64, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x27, 0x6e, 0x6f, 0x6e, 0x2d, 0x62, 0x61, 0x63, 0x6b, + 0x77, 0x61, 0x72, 0x64, 0x73, 0x2d, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x74, + 0x69, 0x62, 0x6c, 0x65, 0x27, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, + 0x65, 0x6e, 0x74, 0x20, 0x69, 0x73, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x69, 0x66, 0x20, 0x74, 0x68, 0x65, 0x79, 0x20, 0x62, 0x65, + 0x6c, 0x69, 0x65, 0x76, 0x65, 0x20, 0x61, 0x20, 0x63, 0x68, 0x61, 0x6e, + 0x67, 0x65, 0x20, 0x63, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x6e, 0x65, 0x67, + 0x61, 0x74, 0x69, 0x76, 0x65, 0x6c, 0x79, 0x20, 0x69, 0x6d, 0x70, 0x61, + 0x63, 0x74, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x20, 0x65, + 0x76, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, + 0x68, 0x6f, 0x75, 0x67, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x61, + 0x63, 0x6b, 0x77, 0x61, 0x72, 0x64, 0x73, 0x20, 0x63, 0x6f, 0x6d, 0x70, + 0x61, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x20, 0x72, 0x75, + 0x6c, 0x65, 0x73, 0x20, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x20, + 0x69, 0x6e, 0x20, 0x52, 0x46, 0x43, 0x2d, 0x58, 0x58, 0x58, 0x58, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x69, 0x66, 0x79, 0x20, 0x69, 0x74, 0x20, 0x61, 0x73, 0x20, 0x61, 0x20, + 0x62, 0x61, 0x63, 0x6b, 0x77, 0x61, 0x72, 0x64, 0x73, 0x2d, 0x63, 0x6f, + 0x6d, 0x70, 0x61, 0x74, 0x69, 0x62, 0x6c, 0x65, 0x20, 0x63, 0x68, 0x61, + 0x6e, 0x67, 0x65, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x41, 0x64, 0x64, 0x2c, 0x20, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x69, + 0x6e, 0x67, 0x2c, 0x20, 0x6f, 0x72, 0x20, 0x63, 0x68, 0x61, 0x6e, 0x67, + 0x69, 0x6e, 0x67, 0x20, 0x61, 0x20, 0x27, 0x6e, 0x6f, 0x6e, 0x2d, 0x62, + 0x61, 0x63, 0x6b, 0x77, 0x61, 0x72, 0x64, 0x73, 0x2d, 0x63, 0x6f, 0x6d, + 0x70, 0x61, 0x74, 0x69, 0x62, 0x6c, 0x65, 0x27, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, + 0x74, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x77, + 0x61, 0x72, 0x64, 0x73, 0x2d, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x74, 0x69, + 0x62, 0x6c, 0x65, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, + 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 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, 0x58, 0x58, 0x58, 0x58, 0x3a, + 0x20, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x20, 0x59, 0x41, 0x4e, + 0x47, 0x20, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x20, 0x52, 0x65, 0x76, + 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x69, + 0x6e, 0x67, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, + 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x33, 0x2e, 0x32, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6e, 0x6f, 0x6e, 0x2d, 0x62, + 0x61, 0x63, 0x6b, 0x77, 0x61, 0x72, 0x64, 0x73, 0x2d, 0x63, 0x6f, 0x6d, + 0x70, 0x61, 0x74, 0x69, 0x62, 0x6c, 0x65, 0x20, 0x65, 0x78, 0x74, 0x65, + 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, + 0x65, 0x6e, 0x74, 0x22, 0x3b, 0x0a, 0x20, 0x20, 0x7d, 0x0a, 0x0a, 0x20, + 0x20, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x72, + 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x2d, 0x6d, + 0x69, 0x6e, 0x2d, 0x64, 0x61, 0x74, 0x65, 0x20, 0x7b, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x72, + 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2d, 0x64, 0x61, 0x74, 0x65, + 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, 0x52, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x64, 0x73, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, + 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6d, 0x6f, 0x64, 0x75, + 0x6c, 0x65, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x6d, 0x61, 0x79, 0x20, + 0x62, 0x65, 0x20, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x20, + 0x74, 0x6f, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x6e, + 0x65, 0x20, 0x77, 0x68, 0x6f, 0x73, 0x65, 0x20, 0x72, 0x65, 0x76, 0x69, + 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x64, 0x61, 0x74, 0x65, 0x20, 0x6d, 0x61, + 0x74, 0x63, 0x68, 0x65, 0x73, 0x20, 0x6f, 0x72, 0x20, 0x69, 0x73, 0x20, + 0x61, 0x66, 0x74, 0x65, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x70, + 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2d, + 0x64, 0x61, 0x74, 0x65, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x54, 0x68, 0x65, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, + 0x6e, 0x74, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x4d, 0x55, 0x53, + 0x54, 0x20, 0x63, 0x6f, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x74, 0x6f, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x27, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, + 0x6f, 0x6e, 0x2d, 0x64, 0x61, 0x74, 0x65, 0x27, 0x20, 0x64, 0x65, 0x66, + 0x69, 0x6e, 0x65, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x74, 0x79, 0x70, 0x65, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x54, 0x68, 0x65, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, + 0x65, 0x6e, 0x74, 0x20, 0x4d, 0x55, 0x53, 0x54, 0x20, 0x6f, 0x6e, 0x6c, + 0x79, 0x20, 0x62, 0x65, 0x20, 0x61, 0x20, 0x73, 0x75, 0x62, 0x73, 0x74, + 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, + 0x6e, 0x74, 0x2e, 0x20, 0x20, 0x5a, 0x65, 0x72, 0x6f, 0x2c, 0x20, 0x6f, + 0x6e, 0x65, 0x20, 0x6f, 0x72, 0x20, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x27, + 0x72, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x2d, + 0x6d, 0x69, 0x6e, 0x2d, 0x64, 0x61, 0x74, 0x65, 0x27, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, + 0x6e, 0x74, 0x73, 0x20, 0x70, 0x65, 0x72, 0x20, 0x70, 0x61, 0x72, 0x65, + 0x6e, 0x74, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, + 0x20, 0x61, 0x72, 0x65, 0x20, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, + 0x2e, 0x20, 0x20, 0x4e, 0x6f, 0x20, 0x73, 0x75, 0x62, 0x73, 0x74, 0x61, + 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, + 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x68, 0x61, + 0x76, 0x65, 0x20, 0x62, 0x65, 0x65, 0x6e, 0x20, 0x73, 0x74, 0x61, 0x6e, + 0x64, 0x61, 0x72, 0x64, 0x69, 0x7a, 0x65, 0x64, 0x2e, 0x0a, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5a, 0x65, 0x72, 0x6f, 0x20, 0x6f, + 0x72, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x27, 0x72, 0x65, 0x63, 0x6f, 0x6d, + 0x6d, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x2d, 0x6d, 0x69, 0x6e, 0x2d, 0x64, + 0x61, 0x74, 0x65, 0x27, 0x20, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, + 0x6f, 0x6e, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, + 0x20, 0x69, 0x73, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, + 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x65, + 0x61, 0x63, 0x68, 0x20, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x20, 0x27, + 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x27, 0x20, 0x73, 0x74, 0x61, 0x74, + 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x41, 0x20, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x75, + 0x6c, 0x61, 0x72, 0x20, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, + 0x20, 0x6f, 0x66, 0x20, 0x61, 0x6e, 0x20, 0x69, 0x6d, 0x70, 0x6f, 0x72, + 0x74, 0x65, 0x64, 0x20, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x20, 0x61, + 0x64, 0x68, 0x65, 0x72, 0x65, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x6e, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x6d, 0x70, 0x6f, + 0x72, 0x74, 0x27, 0x73, 0x20, 0x27, 0x72, 0x65, 0x63, 0x6f, 0x6d, 0x6d, + 0x65, 0x6e, 0x64, 0x65, 0x64, 0x2d, 0x6d, 0x69, 0x6e, 0x2d, 0x64, 0x61, + 0x74, 0x65, 0x27, 0x20, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, + 0x6e, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x20, + 0x69, 0x66, 0x20, 0x74, 0x68, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x20, 0x6d, + 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x27, 0x73, 0x20, 0x72, 0x65, 0x76, 0x69, + 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x64, 0x61, 0x74, 0x65, 0x20, 0x69, 0x73, + 0x20, 0x65, 0x71, 0x75, 0x61, 0x6c, 0x20, 0x74, 0x6f, 0x20, 0x6f, 0x72, + 0x20, 0x6c, 0x61, 0x74, 0x65, 0x72, 0x20, 0x74, 0x68, 0x61, 0x6e, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, + 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x64, 0x61, 0x74, 0x65, + 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x6f, 0x66, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x27, 0x72, 0x65, 0x63, 0x6f, 0x6d, 0x6d, + 0x65, 0x6e, 0x64, 0x65, 0x64, 0x2d, 0x6d, 0x69, 0x6e, 0x2d, 0x64, 0x61, + 0x74, 0x65, 0x27, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, + 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x73, 0x74, 0x61, + 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x20, + 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x41, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x2c, 0x20, + 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x69, 0x6e, 0x67, 0x20, 0x6f, 0x72, 0x20, + 0x75, 0x70, 0x64, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x20, 0x27, + 0x72, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x2d, + 0x6d, 0x69, 0x6e, 0x2d, 0x64, 0x61, 0x74, 0x65, 0x27, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, + 0x6e, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x6e, 0x20, 0x69, 0x6d, 0x70, + 0x6f, 0x72, 0x74, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x62, 0x61, 0x63, + 0x6b, 0x77, 0x61, 0x72, 0x64, 0x73, 0x2d, 0x63, 0x6f, 0x6d, 0x70, 0x61, + 0x74, 0x69, 0x62, 0x6c, 0x65, 0x20, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, + 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, 0x58, 0x58, 0x58, 0x58, 0x3a, 0x20, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x64, 0x20, 0x59, 0x41, 0x4e, 0x47, 0x20, 0x4d, 0x6f, 0x64, 0x75, + 0x6c, 0x65, 0x20, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x20, + 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x69, 0x6e, 0x67, 0x3b, 0x20, 0x53, 0x65, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x34, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x47, 0x75, 0x69, 0x64, 0x61, 0x6e, 0x63, 0x65, + 0x20, 0x66, 0x6f, 0x72, 0x20, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, + 0x6e, 0x20, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x6f, 0x6e, 0x20, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x22, 0x3b, + 0x0a, 0x20, 0x20, 0x7d, 0x0a, 0x7d, 0x0a, 0x00 +}; diff --git a/models/ietf-yang-revisions@2025-01-28.yang b/models/ietf-yang-revisions@2025-01-28.yang new file mode 100644 index 000000000..eab4ae882 --- /dev/null +++ b/models/ietf-yang-revisions@2025-01-28.yang @@ -0,0 +1,146 @@ +module ietf-yang-revisions { + yang-version 1.1; + namespace "urn:ietf:params:xml:ns:yang:ietf-yang-revisions"; + prefix rev; + + import ietf-yang-types { + prefix yang; + reference + "RFC YYYY-draft-ietf-netmod-rfc6991-bis: Common YANG Data Types"; + } + + organization + "IETF NETMOD (Network Modeling) Working Group"; + contact + "WG Web: + WG List: + + Author: Joe Clarke + + + Author: Reshad Rahman + + + Author: Robert Wilton + + + Author: Balazs Lengyel + + + Author: Jason Sterne + "; + description + "This YANG 1.1 module contains definitions and extensions to + support updated YANG revision handling. + + Copyright (c) 2024 IETF Trust and the persons identified as + authors of the code. All rights reserved. + + Redistribution and use in source and binary forms, with or + without modification, is permitted pursuant to, and subject to + the license terms contained in, the Revised BSD License set + forth in Section 4.c of the IETF Trust's Legal Provisions + Relating to IETF Documents + (https://trustee.ietf.org/license-info). + + This version of this YANG module is part of RFC XXXX; see + the RFC itself for full legal notices. + + The key words 'MUST', 'MUST NOT', 'REQUIRED', 'SHALL', 'SHALL + NOT', 'SHOULD', 'SHOULD NOT', 'RECOMMENDED', 'NOT RECOMMENDED', + 'MAY', and 'OPTIONAL' in this document are to be interpreted as + described in BCP 14 (RFC 2119) (RFC 8174) when, and only when, + they appear in all capitals, as shown here."; + // RFC Ed.: update the date below with the date of RFC publication + // and remove this note. + // RFC Ed.: replace XXXX (inc above) with actual RFC number and + // remove this note. + // RFC Ed.: replace YYYY-draft-ietf-netmod-rfc6991-bis (inc above) with actual RFC number and + // remove this note. + + revision 2025-01-28 { + description + "Initial version."; + reference + "RFC XXXX: Updated YANG Module Revision Handling"; + } + + typedef revision-date { + type yang:date-no-zone; + description + "A date associated with a YANG revision. + + Matches dates formatted as YYYY-MM-DD."; + reference + "RFC 7950: The YANG 1.1 Data Modeling Language"; + } + + extension non-backwards-compatible { + description + "This statement is used to indicate YANG module revisions that + contain non-backwards-compatible changes. + + The statement MUST only be a substatement of the 'revision' + statement. Zero or one 'non-backwards-compatible' statements + per parent statement is allowed. No substatements for this + extension have been standardized. + + If a revision of a YANG module contains changes, relative to + the preceding revision in the revision history, that do not + conform to the backwards-compatible module update rules + defined in RFC-XXXX, then the 'non-backwards-compatible' + statement MUST be added as a substatement to the revision + statement. + + Conversely, if a revision does not contain a + 'non-backwards-compatible' statement then all changes, + relative to the preceding revision in the revision history, + MUST be backwards-compatible. + + A new module revision that only contains changes that are + backwards-compatible SHOULD NOT include the + 'non-backwards-compatible' statement. An example of when an + author might add the 'non-backwards-compatible' statement is + if they believe a change could negatively impact clients even + though the backwards compatibility rules defined in RFC-XXXX + classify it as a backwards-compatible change. + + Add, removing, or changing a 'non-backwards-compatible' + statement is a backwards-compatible version change."; + reference + "XXXX: Updated YANG Module Revision Handling; + Section 3.2, + non-backwards-compatible extension statement"; + } + + extension recommended-min-date { + argument revision-date; + description + "Recommends the revision of the module that may be imported to + one whose revision date matches or is after the specified + revision-date. + + The argument value MUST conform to the 'revision-date' defined + type. + + The statement MUST only be a substatement of the import + statement. Zero, one or more 'recommended-min-date' + statements per parent statement are allowed. No substatements + for this extension have been standardized. + + Zero or one 'recommended-min-date' extension statement is + allowed for each parent 'import' statement. + + A particular revision of an imported module adheres to an + import's 'recommended-min-date' extension statement if the + imported module's revision date is equal to or later than + the revision date argument of the 'recommended-min-date' + extension statement in the importing module. + + Adding, removing or updating a 'recommended-min-date' + statement to an import is a backwards-compatible change."; + reference + "XXXX: Updated YANG Module Revision Handling; Section 4, + Guidance for revision selection on imports"; + } +} diff --git a/models/ietf-yang-semver@2025-09-29.h b/models/ietf-yang-semver@2025-09-29.h new file mode 100644 index 000000000..1cb7ac196 --- /dev/null +++ b/models/ietf-yang-semver@2025-09-29.h @@ -0,0 +1,418 @@ +unsigned char ietf_yang_semver_2025_09_29_yang[] = { + 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x20, 0x69, 0x65, 0x74, 0x66, 0x2d, + 0x79, 0x61, 0x6e, 0x67, 0x2d, 0x73, 0x65, 0x6d, 0x76, 0x65, 0x72, 0x20, + 0x7b, 0x0a, 0x20, 0x20, 0x79, 0x61, 0x6e, 0x67, 0x2d, 0x76, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x31, 0x2e, 0x31, 0x3b, 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, 0x69, 0x65, 0x74, 0x66, 0x2d, 0x79, 0x61, 0x6e, 0x67, + 0x2d, 0x73, 0x65, 0x6d, 0x76, 0x65, 0x72, 0x22, 0x3b, 0x0a, 0x20, 0x20, + 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x20, 0x79, 0x73, 0x76, 0x3b, 0x0a, + 0x0a, 0x20, 0x20, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, 0x49, 0x45, 0x54, + 0x46, 0x20, 0x4e, 0x45, 0x54, 0x4d, 0x4f, 0x44, 0x20, 0x28, 0x4e, 0x65, + 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x20, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x69, + 0x6e, 0x67, 0x29, 0x20, 0x57, 0x6f, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x20, + 0x47, 0x72, 0x6f, 0x75, 0x70, 0x22, 0x3b, 0x0a, 0x20, 0x20, 0x63, 0x6f, + 0x6e, 0x74, 0x61, 0x63, 0x74, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, 0x57, + 0x47, 0x20, 0x57, 0x65, 0x62, 0x3a, 0x20, 0x20, 0x20, 0x3c, 0x68, 0x74, + 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x74, 0x72, 0x61, + 0x63, 0x6b, 0x65, 0x72, 0x2e, 0x69, 0x65, 0x74, 0x66, 0x2e, 0x6f, 0x72, + 0x67, 0x2f, 0x77, 0x67, 0x2f, 0x6e, 0x65, 0x74, 0x6d, 0x6f, 0x64, 0x2f, + 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x57, 0x47, 0x20, 0x4c, 0x69, + 0x73, 0x74, 0x3a, 0x20, 0x20, 0x3c, 0x6d, 0x61, 0x69, 0x6c, 0x74, 0x6f, + 0x3a, 0x6e, 0x65, 0x74, 0x6d, 0x6f, 0x64, 0x40, 0x69, 0x65, 0x74, 0x66, + 0x2e, 0x6f, 0x72, 0x67, 0x3e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x3a, 0x20, 0x20, 0x20, 0x4a, 0x6f, + 0x65, 0x20, 0x43, 0x6c, 0x61, 0x72, 0x6b, 0x65, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x3c, 0x6d, 0x61, 0x69, 0x6c, 0x74, 0x6f, 0x3a, 0x6a, 0x63, 0x6c, 0x61, + 0x72, 0x6b, 0x65, 0x40, 0x63, 0x69, 0x73, 0x63, 0x6f, 0x2e, 0x63, 0x6f, + 0x6d, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x41, 0x75, 0x74, 0x68, + 0x6f, 0x72, 0x3a, 0x20, 0x20, 0x20, 0x52, 0x6f, 0x62, 0x65, 0x72, 0x74, + 0x20, 0x57, 0x69, 0x6c, 0x74, 0x6f, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, + 0x6d, 0x61, 0x69, 0x6c, 0x74, 0x6f, 0x3a, 0x72, 0x77, 0x69, 0x6c, 0x74, + 0x6f, 0x6e, 0x40, 0x63, 0x69, 0x73, 0x63, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, + 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, + 0x72, 0x3a, 0x20, 0x20, 0x20, 0x52, 0x65, 0x73, 0x68, 0x61, 0x64, 0x20, + 0x52, 0x61, 0x68, 0x6d, 0x61, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x6d, + 0x61, 0x69, 0x6c, 0x74, 0x6f, 0x3a, 0x72, 0x65, 0x73, 0x68, 0x61, 0x64, + 0x40, 0x79, 0x61, 0x68, 0x6f, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x3e, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x3a, + 0x20, 0x20, 0x20, 0x42, 0x61, 0x6c, 0x61, 0x7a, 0x73, 0x20, 0x4c, 0x65, + 0x6e, 0x67, 0x79, 0x65, 0x6c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x6d, 0x61, + 0x69, 0x6c, 0x74, 0x6f, 0x3a, 0x62, 0x61, 0x6c, 0x61, 0x7a, 0x73, 0x2e, + 0x6c, 0x65, 0x6e, 0x67, 0x79, 0x65, 0x6c, 0x40, 0x65, 0x72, 0x69, 0x63, + 0x73, 0x73, 0x6f, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x3e, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x3a, 0x20, 0x20, + 0x20, 0x4a, 0x61, 0x73, 0x6f, 0x6e, 0x20, 0x53, 0x74, 0x65, 0x72, 0x6e, + 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x6d, 0x61, 0x69, 0x6c, 0x74, 0x6f, + 0x3a, 0x6a, 0x61, 0x73, 0x6f, 0x6e, 0x2e, 0x73, 0x74, 0x65, 0x72, 0x6e, + 0x65, 0x40, 0x6e, 0x6f, 0x6b, 0x69, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x3e, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, + 0x3a, 0x20, 0x20, 0x20, 0x42, 0x65, 0x6e, 0x6f, 0x69, 0x74, 0x20, 0x43, + 0x6c, 0x61, 0x69, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x6d, 0x61, + 0x69, 0x6c, 0x74, 0x6f, 0x3a, 0x62, 0x65, 0x6e, 0x6f, 0x69, 0x74, 0x40, + 0x65, 0x76, 0x65, 0x72, 0x79, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x2d, 0x6f, + 0x70, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x3e, 0x22, 0x3b, 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, 0x6d, 0x6f, + 0x64, 0x75, 0x6c, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, + 0x73, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x67, + 0x72, 0x6f, 0x75, 0x70, 0x69, 0x6e, 0x67, 0x20, 0x64, 0x65, 0x66, 0x69, + 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x66, 0x6f, 0x72, 0x20, + 0x59, 0x41, 0x4e, 0x47, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x61, + 0x63, 0x6b, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, + 0x28, 0x63, 0x29, 0x20, 0x32, 0x30, 0x32, 0x35, 0x20, 0x49, 0x45, 0x54, + 0x46, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x61, 0x6e, 0x64, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x70, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x73, 0x20, + 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x20, 0x61, + 0x73, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6f, + 0x72, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, + 0x64, 0x65, 0x2e, 0x20, 0x20, 0x41, 0x6c, 0x6c, 0x20, 0x72, 0x69, 0x67, + 0x68, 0x74, 0x73, 0x20, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, + 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x52, 0x65, 0x64, 0x69, + 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, + 0x6e, 0x64, 0x20, 0x75, 0x73, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x62, 0x69, 0x6e, + 0x61, 0x72, 0x79, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x73, 0x2c, 0x20, 0x77, + 0x69, 0x74, 0x68, 0x20, 0x6f, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x77, 0x69, 0x74, 0x68, 0x6f, 0x75, 0x74, 0x20, 0x6d, 0x6f, 0x64, 0x69, + 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x69, 0x73, + 0x20, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x64, 0x20, 0x70, + 0x75, 0x72, 0x73, 0x75, 0x61, 0x6e, 0x74, 0x20, 0x74, 0x6f, 0x2c, 0x20, + 0x61, 0x6e, 0x64, 0x20, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, + 0x6c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x20, 0x74, 0x65, 0x72, 0x6d, + 0x73, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x64, 0x20, + 0x69, 0x6e, 0x2c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x52, 0x65, 0x76, 0x69, + 0x73, 0x65, 0x64, 0x20, 0x42, 0x53, 0x44, 0x20, 0x4c, 0x69, 0x63, 0x65, + 0x6e, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x65, 0x74, + 0x20, 0x66, 0x6f, 0x72, 0x74, 0x68, 0x20, 0x69, 0x6e, 0x20, 0x53, 0x65, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x34, 0x2e, 0x63, 0x20, 0x6f, 0x66, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x49, 0x45, 0x54, 0x46, 0x20, 0x54, 0x72, + 0x75, 0x73, 0x74, 0x27, 0x73, 0x20, 0x4c, 0x65, 0x67, 0x61, 0x6c, 0x20, + 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6e, 0x67, + 0x20, 0x74, 0x6f, 0x20, 0x49, 0x45, 0x54, 0x46, 0x20, 0x44, 0x6f, 0x63, + 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x28, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x74, 0x72, 0x75, 0x73, + 0x74, 0x65, 0x65, 0x2e, 0x69, 0x65, 0x74, 0x66, 0x2e, 0x6f, 0x72, 0x67, + 0x2f, 0x6c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x2d, 0x69, 0x6e, 0x66, + 0x6f, 0x29, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x54, 0x68, + 0x65, 0x20, 0x6b, 0x65, 0x79, 0x20, 0x77, 0x6f, 0x72, 0x64, 0x73, 0x20, + 0x27, 0x4d, 0x55, 0x53, 0x54, 0x27, 0x2c, 0x20, 0x27, 0x4d, 0x55, 0x53, + 0x54, 0x20, 0x4e, 0x4f, 0x54, 0x27, 0x2c, 0x20, 0x27, 0x52, 0x45, 0x51, + 0x55, 0x49, 0x52, 0x45, 0x44, 0x27, 0x2c, 0x20, 0x27, 0x53, 0x48, 0x41, + 0x4c, 0x4c, 0x27, 0x2c, 0x20, 0x27, 0x53, 0x48, 0x41, 0x4c, 0x4c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x4e, 0x4f, 0x54, 0x27, 0x2c, 0x20, 0x27, + 0x53, 0x48, 0x4f, 0x55, 0x4c, 0x44, 0x27, 0x2c, 0x20, 0x27, 0x53, 0x48, + 0x4f, 0x55, 0x4c, 0x44, 0x20, 0x4e, 0x4f, 0x54, 0x27, 0x2c, 0x20, 0x27, + 0x52, 0x45, 0x43, 0x4f, 0x4d, 0x4d, 0x45, 0x4e, 0x44, 0x45, 0x44, 0x27, + 0x2c, 0x20, 0x27, 0x4e, 0x4f, 0x54, 0x20, 0x52, 0x45, 0x43, 0x4f, 0x4d, + 0x4d, 0x45, 0x4e, 0x44, 0x45, 0x44, 0x27, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x27, 0x4d, 0x41, 0x59, 0x27, 0x2c, 0x20, 0x61, 0x6e, 0x64, + 0x20, 0x27, 0x4f, 0x50, 0x54, 0x49, 0x4f, 0x4e, 0x41, 0x4c, 0x27, 0x20, + 0x69, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x64, 0x6f, 0x63, 0x75, + 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x61, 0x72, 0x65, 0x20, 0x74, 0x6f, 0x20, + 0x62, 0x65, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, + 0x65, 0x64, 0x20, 0x61, 0x73, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, + 0x65, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, + 0x42, 0x43, 0x50, 0x20, 0x31, 0x34, 0x20, 0x28, 0x52, 0x46, 0x43, 0x20, + 0x32, 0x31, 0x31, 0x39, 0x29, 0x20, 0x28, 0x52, 0x46, 0x43, 0x20, 0x38, + 0x31, 0x37, 0x34, 0x29, 0x20, 0x77, 0x68, 0x65, 0x6e, 0x2c, 0x20, 0x61, + 0x6e, 0x64, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x77, 0x68, 0x65, 0x6e, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x68, 0x65, 0x79, 0x20, + 0x61, 0x70, 0x70, 0x65, 0x61, 0x72, 0x20, 0x69, 0x6e, 0x20, 0x61, 0x6c, + 0x6c, 0x20, 0x63, 0x61, 0x70, 0x69, 0x74, 0x61, 0x6c, 0x73, 0x2c, 0x20, + 0x61, 0x73, 0x20, 0x73, 0x68, 0x6f, 0x77, 0x6e, 0x20, 0x68, 0x65, 0x72, + 0x65, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x54, 0x68, 0x69, + 0x73, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, + 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x59, 0x41, 0x4e, 0x47, 0x20, 0x6d, + 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x20, 0x69, 0x73, 0x20, 0x70, 0x61, 0x72, + 0x74, 0x20, 0x6f, 0x66, 0x20, 0x52, 0x46, 0x43, 0x20, 0x58, 0x58, 0x58, + 0x58, 0x3b, 0x20, 0x73, 0x65, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x52, 0x46, 0x43, 0x20, 0x69, 0x74, 0x73, 0x65, + 0x6c, 0x66, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x66, 0x75, 0x6c, 0x6c, 0x20, + 0x6c, 0x65, 0x67, 0x61, 0x6c, 0x20, 0x6e, 0x6f, 0x74, 0x69, 0x63, 0x65, + 0x73, 0x2e, 0x22, 0x3b, 0x0a, 0x0a, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x52, + 0x46, 0x43, 0x20, 0x45, 0x64, 0x2e, 0x3a, 0x20, 0x75, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x64, 0x61, 0x74, 0x65, 0x20, + 0x62, 0x65, 0x6c, 0x6f, 0x77, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x64, 0x61, 0x74, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x52, + 0x46, 0x43, 0x20, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x0a, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x61, 0x6e, 0x64, 0x20, + 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, + 0x6e, 0x6f, 0x74, 0x65, 0x2e, 0x0a, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x52, + 0x46, 0x43, 0x20, 0x45, 0x64, 0x2e, 0x3a, 0x20, 0x72, 0x65, 0x70, 0x6c, + 0x61, 0x63, 0x65, 0x20, 0x58, 0x58, 0x58, 0x58, 0x20, 0x77, 0x69, 0x74, + 0x68, 0x20, 0x61, 0x63, 0x74, 0x75, 0x61, 0x6c, 0x20, 0x52, 0x46, 0x43, + 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x61, 0x6e, 0x64, 0x20, + 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x20, 0x74, 0x68, 0x69, 0x73, 0x0a, + 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x6e, 0x6f, 0x74, 0x65, 0x2e, 0x0a, 0x20, + 0x20, 0x2f, 0x2f, 0x20, 0x52, 0x46, 0x43, 0x20, 0x45, 0x64, 0x2e, 0x20, + 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x79, + 0x73, 0x76, 0x3a, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x74, + 0x6f, 0x20, 0x22, 0x31, 0x2e, 0x30, 0x2e, 0x30, 0x22, 0x2e, 0x0a, 0x0a, + 0x20, 0x20, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x32, + 0x30, 0x32, 0x35, 0x2d, 0x30, 0x39, 0x2d, 0x32, 0x39, 0x20, 0x7b, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x79, 0x73, 0x76, 0x3a, 0x76, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x20, 0x22, 0x30, 0x2e, 0x32, 0x34, 0x2e, 0x30, 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, 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, 0x58, 0x58, 0x58, + 0x58, 0x3a, 0x20, 0x59, 0x41, 0x4e, 0x47, 0x20, 0x53, 0x65, 0x6d, 0x61, + 0x6e, 0x74, 0x69, 0x63, 0x20, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, + 0x69, 0x6e, 0x67, 0x2e, 0x22, 0x3b, 0x0a, 0x20, 0x20, 0x7d, 0x0a, 0x0a, + 0x20, 0x20, 0x2f, 0x2a, 0x0a, 0x20, 0x20, 0x20, 0x2a, 0x20, 0x45, 0x78, + 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x0a, 0x20, 0x20, 0x20, + 0x2a, 0x2f, 0x0a, 0x0a, 0x20, 0x20, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, + 0x69, 0x6f, 0x6e, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, + 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, + 0x6e, 0x74, 0x20, 0x79, 0x61, 0x6e, 0x67, 0x2d, 0x73, 0x65, 0x6d, 0x61, + 0x6e, 0x74, 0x69, 0x63, 0x2d, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 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, 0x54, 0x68, 0x65, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, + 0x20, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x69, + 0x73, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x73, + 0x73, 0x69, 0x67, 0x6e, 0x20, 0x61, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x20, 0x6d, 0x6f, + 0x64, 0x75, 0x6c, 0x65, 0x20, 0x6f, 0x72, 0x20, 0x73, 0x75, 0x62, 0x6d, + 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x20, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, + 0x6f, 0x6e, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x54, 0x68, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x20, 0x6f, + 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 0x20, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x20, + 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x4d, 0x55, 0x53, + 0x54, 0x20, 0x63, 0x6f, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, + 0x27, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x27, 0x20, 0x74, 0x79, + 0x70, 0x65, 0x64, 0x65, 0x66, 0x20, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, + 0x64, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x6d, 0x6f, + 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x54, 0x68, 0x65, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, + 0x65, 0x6e, 0x74, 0x20, 0x4d, 0x55, 0x53, 0x54, 0x20, 0x6f, 0x6e, 0x6c, + 0x79, 0x20, 0x62, 0x65, 0x20, 0x61, 0x20, 0x73, 0x75, 0x62, 0x73, 0x74, + 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, + 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x20, 0x20, 0x5a, 0x65, 0x72, 0x6f, 0x20, + 0x6f, 0x72, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, + 0x73, 0x20, 0x70, 0x65, 0x72, 0x20, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x74, 0x61, 0x74, + 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x61, 0x72, 0x65, 0x20, 0x61, 0x6c, + 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x2e, 0x20, 0x20, 0x4e, 0x6f, 0x20, 0x73, + 0x75, 0x62, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, + 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x65, 0x78, + 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x68, 0x61, 0x76, 0x65, 0x20, 0x62, 0x65, 0x65, 0x6e, + 0x20, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x69, 0x7a, 0x65, + 0x64, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x56, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x4d, 0x55, 0x53, 0x54, + 0x20, 0x62, 0x65, 0x20, 0x75, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x20, 0x61, + 0x6d, 0x6f, 0x6e, 0x67, 0x73, 0x74, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x72, + 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6f, 0x66, 0x20, + 0x61, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x6f, 0x64, + 0x75, 0x6c, 0x65, 0x20, 0x6f, 0x72, 0x20, 0x73, 0x75, 0x62, 0x6d, 0x6f, + 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x41, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x2c, 0x20, 0x63, 0x68, + 0x61, 0x6e, 0x67, 0x69, 0x6e, 0x67, 0x20, 0x6f, 0x72, 0x20, 0x72, 0x65, + 0x6d, 0x6f, 0x76, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x20, 0x76, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x77, 0x61, + 0x72, 0x64, 0x73, 0x2d, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x74, 0x69, 0x62, + 0x6c, 0x65, 0x20, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 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, 0x58, 0x58, 0x58, 0x58, 0x3a, 0x20, 0x59, 0x41, 0x4e, 0x47, + 0x20, 0x53, 0x65, 0x6d, 0x61, 0x6e, 0x74, 0x69, 0x63, 0x20, 0x56, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x69, 0x6e, 0x67, 0x3b, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x53, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x34, 0x2e, 0x32, 0x2c, 0x20, 0x59, 0x41, 0x4e, 0x47, 0x20, 0x53, + 0x65, 0x6d, 0x61, 0x6e, 0x74, 0x69, 0x63, 0x20, 0x56, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x20, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, + 0x6e, 0x22, 0x3b, 0x0a, 0x20, 0x20, 0x7d, 0x0a, 0x0a, 0x20, 0x20, 0x65, + 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x65, 0x63, + 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x2d, 0x6d, 0x69, 0x6e, + 0x2d, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x7b, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x20, + 0x79, 0x61, 0x6e, 0x67, 0x2d, 0x73, 0x65, 0x6d, 0x61, 0x6e, 0x74, 0x69, + 0x63, 0x2d, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 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, 0x52, 0x65, + 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x64, 0x73, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6f, 0x66, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x20, + 0x74, 0x68, 0x61, 0x74, 0x20, 0x6d, 0x61, 0x79, 0x20, 0x62, 0x65, 0x20, + 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x74, + 0x68, 0x61, 0x74, 0x20, 0x69, 0x73, 0x20, 0x67, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x72, 0x20, 0x74, 0x68, 0x61, 0x6e, 0x20, 0x6f, 0x72, 0x20, 0x65, + 0x71, 0x75, 0x61, 0x6c, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, + 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x64, 0x20, 0x76, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x54, 0x68, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x61, + 0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x65, 0x63, + 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x2d, 0x6d, 0x69, 0x6e, + 0x2d, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x65, 0x78, 0x74, + 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, + 0x65, 0x6e, 0x74, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6d, + 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x4d, + 0x41, 0x4a, 0x4f, 0x52, 0x2e, 0x4d, 0x49, 0x4e, 0x4f, 0x52, 0x2e, 0x50, + 0x41, 0x54, 0x43, 0x48, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, + 0x6e, 0x74, 0x73, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x74, 0x68, 0x65, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x27, 0x76, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x27, 0x20, 0x74, 0x79, 0x70, 0x65, 0x64, 0x65, + 0x66, 0x20, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x20, 0x69, 0x6e, + 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, + 0x20, 0x28, 0x69, 0x2e, 0x65, 0x2e, 0x2c, 0x20, 0x65, 0x78, 0x63, 0x6c, + 0x75, 0x64, 0x69, 0x6e, 0x67, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x27, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x61, + 0x74, 0x69, 0x62, 0x6c, 0x65, 0x27, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x27, + 0x5f, 0x6e, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x74, 0x69, + 0x62, 0x6c, 0x65, 0x27, 0x20, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, + 0x72, 0x73, 0x20, 0x61, 0x73, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x77, 0x65, 0x6c, 0x6c, 0x20, 0x61, 0x73, 0x20, 0x61, 0x6e, 0x79, + 0x20, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x29, 0x2e, 0x0a, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x54, 0x68, 0x65, 0x20, + 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x4d, 0x55, + 0x53, 0x54, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x62, 0x65, 0x20, 0x61, + 0x20, 0x73, 0x75, 0x62, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, + 0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x69, 0x6d, 0x70, + 0x6f, 0x72, 0x74, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, + 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x20, 0x20, 0x5a, + 0x65, 0x72, 0x6f, 0x20, 0x6f, 0x72, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x27, + 0x72, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x2d, + 0x6d, 0x69, 0x6e, 0x2d, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x27, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x74, 0x61, 0x74, + 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x20, 0x70, 0x65, 0x72, 0x20, 0x70, + 0x61, 0x72, 0x65, 0x6e, 0x74, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, + 0x65, 0x6e, 0x74, 0x20, 0x61, 0x72, 0x65, 0x20, 0x61, 0x6c, 0x6c, 0x6f, + 0x77, 0x65, 0x64, 0x2e, 0x20, 0x20, 0x4e, 0x6f, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x73, 0x75, 0x62, 0x73, 0x74, 0x61, 0x74, 0x65, + 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, + 0x69, 0x73, 0x20, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, + 0x20, 0x68, 0x61, 0x76, 0x65, 0x20, 0x62, 0x65, 0x65, 0x6e, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, + 0x72, 0x64, 0x69, 0x7a, 0x65, 0x64, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x41, 0x20, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, + 0x20, 0x74, 0x6f, 0x20, 0x62, 0x65, 0x20, 0x69, 0x6d, 0x70, 0x6f, 0x72, + 0x74, 0x65, 0x64, 0x20, 0x69, 0x73, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x69, + 0x64, 0x65, 0x72, 0x65, 0x64, 0x20, 0x61, 0x73, 0x20, 0x6d, 0x65, 0x65, + 0x74, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, + 0x64, 0x65, 0x64, 0x20, 0x6d, 0x69, 0x6e, 0x69, 0x6d, 0x75, 0x6d, 0x20, + 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x72, 0x69, 0x74, + 0x65, 0x72, 0x69, 0x61, 0x20, 0x69, 0x66, 0x20, 0x69, 0x74, 0x20, 0x6d, + 0x65, 0x65, 0x74, 0x73, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x6f, 0x66, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, + 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x69, 0x6e, 0x67, 0x20, 0x63, 0x6f, 0x6e, + 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x3a, 0x0a, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x2a, 0x20, 0x48, 0x61, 0x73, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x65, 0x78, 0x61, 0x63, 0x74, 0x20, 0x73, 0x61, 0x6d, + 0x65, 0x20, 0x4d, 0x41, 0x4a, 0x4f, 0x52, 0x2c, 0x20, 0x4d, 0x49, 0x4e, + 0x4f, 0x52, 0x2c, 0x20, 0x50, 0x41, 0x54, 0x43, 0x48, 0x20, 0x61, 0x73, + 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x63, 0x6f, 0x6d, 0x6d, + 0x65, 0x6e, 0x64, 0x65, 0x64, 0x2d, 0x6d, 0x69, 0x6e, 0x2d, 0x76, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2e, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2a, 0x20, 0x48, 0x61, + 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x61, 0x6d, 0x65, 0x20, 0x4d, + 0x41, 0x4a, 0x4f, 0x52, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x4d, 0x49, 0x4e, + 0x4f, 0x52, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x6e, + 0x75, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x61, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x67, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x72, 0x20, 0x50, 0x41, 0x54, 0x43, 0x48, 0x20, + 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x2e, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x2a, 0x20, 0x48, 0x61, 0x73, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x73, 0x61, 0x6d, 0x65, 0x20, 0x4d, 0x41, 0x4a, 0x4f, 0x52, 0x20, + 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x6e, 0x75, 0x6d, 0x62, + 0x65, 0x72, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x67, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x72, 0x20, 0x4d, 0x49, 0x4e, 0x4f, 0x52, 0x20, 0x6e, 0x75, 0x6d, + 0x62, 0x65, 0x72, 0x2e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x49, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x63, 0x61, + 0x73, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x50, 0x41, 0x54, 0x43, 0x48, + 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x69, 0x73, 0x20, 0x69, + 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x64, 0x2e, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x2a, 0x20, 0x48, 0x61, 0x73, 0x20, 0x61, 0x20, 0x67, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x72, 0x20, 0x4d, 0x41, 0x4a, 0x4f, 0x52, + 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x6e, 0x75, 0x6d, + 0x62, 0x65, 0x72, 0x2e, 0x20, 0x20, 0x49, 0x6e, 0x20, 0x74, 0x68, 0x69, + 0x73, 0x20, 0x63, 0x61, 0x73, 0x65, 0x20, 0x4d, 0x49, 0x4e, 0x4f, 0x52, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x6e, + 0x64, 0x20, 0x50, 0x41, 0x54, 0x43, 0x48, 0x20, 0x6e, 0x75, 0x6d, 0x62, + 0x65, 0x72, 0x73, 0x20, 0x61, 0x72, 0x65, 0x20, 0x69, 0x67, 0x6e, 0x6f, + 0x72, 0x65, 0x64, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x41, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x2c, 0x20, 0x72, 0x65, 0x6d, + 0x6f, 0x76, 0x69, 0x6e, 0x67, 0x20, 0x6f, 0x72, 0x20, 0x75, 0x70, 0x64, + 0x61, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x20, 0x27, 0x72, 0x65, 0x63, + 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x2d, 0x6d, 0x69, 0x6e, + 0x2d, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x27, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, + 0x6e, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x6e, 0x20, 0x69, 0x6d, 0x70, + 0x6f, 0x72, 0x74, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x62, 0x61, 0x63, + 0x6b, 0x77, 0x61, 0x72, 0x64, 0x73, 0x2d, 0x63, 0x6f, 0x6d, 0x70, 0x61, + 0x74, 0x69, 0x62, 0x6c, 0x65, 0x20, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, + 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, 0x58, 0x58, 0x58, 0x58, 0x3a, 0x20, 0x59, + 0x41, 0x4e, 0x47, 0x20, 0x53, 0x65, 0x6d, 0x61, 0x6e, 0x74, 0x69, 0x63, + 0x20, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x69, 0x6e, 0x67, 0x3b, + 0x20, 0x53, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x35, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x49, 0x6d, 0x70, 0x6f, 0x72, + 0x74, 0x20, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x20, 0x62, 0x79, 0x20, + 0x53, 0x65, 0x6d, 0x61, 0x6e, 0x74, 0x69, 0x63, 0x20, 0x56, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x3b, 0x0a, 0x20, 0x20, 0x7d, 0x0a, 0x0a, + 0x20, 0x20, 0x2f, 0x2a, 0x0a, 0x20, 0x20, 0x20, 0x2a, 0x20, 0x54, 0x79, + 0x70, 0x65, 0x64, 0x65, 0x66, 0x73, 0x0a, 0x20, 0x20, 0x20, 0x2a, 0x2f, + 0x0a, 0x0a, 0x20, 0x20, 0x74, 0x79, 0x70, 0x65, 0x64, 0x65, 0x66, 0x20, + 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x7b, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, + 0x6e, 0x67, 0x74, 0x68, 0x20, 0x22, 0x35, 0x2e, 0x2e, 0x31, 0x32, 0x38, + 0x22, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x61, 0x74, + 0x74, 0x65, 0x72, 0x6e, 0x20, 0x27, 0x5b, 0x30, 0x2d, 0x39, 0x5d, 0x2b, + 0x5b, 0x2e, 0x5d, 0x5b, 0x30, 0x2d, 0x39, 0x5d, 0x2b, 0x5b, 0x2e, 0x5d, + 0x5b, 0x30, 0x2d, 0x39, 0x5d, 0x2b, 0x28, 0x5f, 0x28, 0x6e, 0x6f, 0x6e, + 0x5f, 0x29, 0x3f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x74, 0x69, 0x62, 0x6c, + 0x65, 0x29, 0x3f, 0x27, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x2b, 0x20, 0x27, 0x28, 0x2d, 0x5b, 0x41, + 0x2d, 0x5a, 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x2e, 0x2d, 0x5d, 0x2b, + 0x5b, 0x2e, 0x2d, 0x5d, 0x5b, 0x30, 0x2d, 0x39, 0x5d, 0x2b, 0x29, 0x3f, + 0x28, 0x5b, 0x2b, 0x5d, 0x5b, 0x41, 0x2d, 0x5a, 0x61, 0x2d, 0x7a, 0x30, + 0x2d, 0x39, 0x2e, 0x2d, 0x5d, 0x2b, 0x29, 0x3f, 0x27, 0x3b, 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, 0x52, 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, + 0x74, 0x73, 0x20, 0x61, 0x20, 0x59, 0x41, 0x4e, 0x47, 0x20, 0x73, 0x65, + 0x6d, 0x61, 0x6e, 0x74, 0x69, 0x63, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x2e, 0x20, 0x20, 0x54, 0x68, 0x65, 0x20, 0x72, 0x75, 0x6c, + 0x65, 0x73, 0x20, 0x67, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x69, 0x6e, 0x67, + 0x20, 0x74, 0x68, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x75, 0x73, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, + 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x64, 0x65, 0x6e, + 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x20, 0x61, 0x72, 0x65, 0x20, 0x64, + 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, + 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x66, + 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, + 0x68, 0x69, 0x73, 0x20, 0x74, 0x79, 0x70, 0x65, 0x64, 0x65, 0x66, 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, 0x58, 0x58, 0x58, 0x58, 0x3a, 0x20, 0x59, 0x41, + 0x4e, 0x47, 0x20, 0x53, 0x65, 0x6d, 0x61, 0x6e, 0x74, 0x69, 0x63, 0x20, + 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x69, 0x6e, 0x67, 0x2e, 0x22, + 0x3b, 0x0a, 0x20, 0x20, 0x7d, 0x0a, 0x7d, 0x0a, 0x00 +}; diff --git a/models/ietf-yang-semver@2025-09-29.yang b/models/ietf-yang-semver@2025-09-29.yang new file mode 100644 index 000000000..e68b202a8 --- /dev/null +++ b/models/ietf-yang-semver@2025-09-29.yang @@ -0,0 +1,144 @@ +module ietf-yang-semver { + yang-version 1.1; + namespace "urn:ietf:params:xml:ns:yang:ietf-yang-semver"; + prefix ysv; + + organization + "IETF NETMOD (Network Modeling) Working Group"; + contact + "WG Web: + WG List: + + Author: Joe Clarke + + Author: Robert Wilton + + Author: Reshad Rahman + + Author: Balazs Lengyel + + Author: Jason Sterne + + Author: Benoit Claise + "; + description + "This module provides type and grouping definitions for YANG + packages. + + Copyright (c) 2025 IETF Trust and the persons identified as + authors of the code. All rights reserved. + + Redistribution and use in source and binary forms, with or + without modification, is permitted pursuant to, and subject + to the license terms contained in, the Revised BSD License + set forth in Section 4.c of the IETF Trust's Legal Provisions + Relating to IETF Documents + (http://trustee.ietf.org/license-info). + + The key words 'MUST', 'MUST NOT', 'REQUIRED', 'SHALL', 'SHALL + NOT', 'SHOULD', 'SHOULD NOT', 'RECOMMENDED', 'NOT RECOMMENDED', + 'MAY', and 'OPTIONAL' in this document are to be interpreted as + described in BCP 14 (RFC 2119) (RFC 8174) when, and only when, + they appear in all capitals, as shown here. + + This version of this YANG module is part of RFC XXXX; see + the RFC itself for full legal notices."; + + // RFC Ed.: update the date below with the date of RFC publication + // and remove this note. + // RFC Ed.: replace XXXX with actual RFC number and remove this + // note. + // RFC Ed. update the ysv:version to "1.0.0". + + revision 2025-09-29 { + ysv:version "0.24.0"; + description + "Initial revision"; + reference + "RFC XXXX: YANG Semantic Versioning."; + } + + /* + * Extensions + */ + + extension version { + argument yang-semantic-version; + description + "The version extension is used to assign a version number + to a module or submodule revision. + + The format of the version extension argument MUST conform + to the 'version' typedef defined in this module. + + The statement MUST only be a substatement of the revision + statement. Zero or one version statements per parent + statement are allowed. No substatements for this extension + have been standardized. + + Versions MUST be unique amongst all revisions of a + module or submodule. + + Adding, changing or removing a version is a + backwards-compatible change."; + reference + "RFC XXXX: YANG Semantic Versioning; + Section 4.2, YANG Semantic Version Extension"; + } + + extension recommended-min-version { + argument yang-semantic-version; + description + "Recommends the versions of the module that may be imported to + one that is greater than or equal to the specified version. + + The format of the recommended-min-version extension argument + must be the MAJOR.MINOR.PATCH components from the + 'version' typedef defined in this module (i.e., excluding + the '_compatible' and '_non_compatible' modifiers as + well as any metadata). + + The statement MUST only be a substatement of the import + statement. Zero or one 'recommended-min-version' + statements per parent statement are allowed. No + substatements for this extension have been + standardized. + + A module to be imported is considered as meeting the + recommended minimum version criteria if it meets one of + the following conditions: + + * Has the exact same MAJOR, MINOR, PATCH as in the + recommended-min-version value. + * Has the same MAJOR and MINOR version numbers and a + greater PATCH number. + * Has the same MAJOR version number and greater MINOR number. + In this case the PATCH number is ignored. + * Has a greater MAJOR version number. In this case MINOR + and PATCH numbers are ignored. + + Adding, removing or updating a 'recommended-min-version' + statement to an import is a backwards-compatible change."; + reference + "RFC XXXX: YANG Semantic Versioning; Section 5, + Import Module by Semantic Version"; + } + + /* + * Typedefs + */ + + typedef version { + type string { + length "5..128"; + pattern '[0-9]+[.][0-9]+[.][0-9]+(_(non_)?compatible)?' + + '(-[A-Za-z0-9.-]+[.-][0-9]+)?([+][A-Za-z0-9.-]+)?'; + } + description + "Represents a YANG semantic version. The rules governing the + use of this version identifier are defined in the + reference for this typedef."; + reference + "RFC XXXX: YANG Semantic Versioning."; + } +} diff --git a/src/context.c b/src/context.c index 68a8ff21e..64b8f5740 100644 --- a/src/context.c +++ b/src/context.c @@ -52,7 +52,9 @@ #include "../models/ietf-inet-types@2013-07-15.h" #include "../models/ietf-yang-library@2019-01-04.h" #include "../models/ietf-yang-metadata@2016-08-05.h" +#include "../models/ietf-yang-revisions@2025-01-28.h" #include "../models/ietf-yang-schema-mount@2019-01-14.h" +#include "../models/ietf-yang-semver@2025-09-29.h" #include "../models/ietf-yang-structure-ext@2020-06-17.h" #include "../models/ietf-yang-types@2013-07-15.h" #include "../models/yang@2025-01-29.h" @@ -69,6 +71,8 @@ static struct internal_modules_s { {"yang", "2025-01-29", (const char *)yang_2025_01_29_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-yang-semver", "2025-09-29", (const char *)ietf_yang_semver_2025_09_29_yang, 0, LYS_IN_YANG}, + {"ietf-yang-revisions", "2025-01-28", (const char *)ietf_yang_revisions_2025_01_28_yang, 0, LYS_IN_YANG}, {"ietf-yang-schema-mount", "2019-01-14", (const char *)ietf_yang_schema_mount_2019_01_14_yang, 1, LYS_IN_YANG}, {"ietf-yang-structure-ext", "2020-06-17", (const char *)ietf_yang_structure_ext_2020_06_17_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/plugins.c b/src/plugins.c index 22c49476b..68455639a 100644 --- a/src/plugins.c +++ b/src/plugins.c @@ -98,6 +98,8 @@ extern struct lyplg_ext_record plugins_nacm[]; extern struct lyplg_ext_record plugins_yangdata[]; extern struct lyplg_ext_record plugins_schema_mount[]; extern struct lyplg_ext_record plugins_structure[]; +extern struct lyplg_ext_record plugins_yang_semver[]; +extern struct lyplg_ext_record plugins_yang_revisions[]; static pthread_mutex_t plugins_guard = PTHREAD_MUTEX_INITIALIZER; @@ -538,6 +540,8 @@ lyplg_init(ly_bool builtin_type_plugins_only) LY_CHECK_GOTO(ret = plugins_insert(NULL, LYPLG_EXTENSION, plugins_yangdata), error); LY_CHECK_GOTO(ret = plugins_insert(NULL, LYPLG_EXTENSION, plugins_schema_mount), error); LY_CHECK_GOTO(ret = plugins_insert(NULL, LYPLG_EXTENSION, plugins_structure), error); + LY_CHECK_GOTO(ret = plugins_insert(NULL, LYPLG_EXTENSION, plugins_yang_semver), error); + LY_CHECK_GOTO(ret = plugins_insert(NULL, LYPLG_EXTENSION, plugins_yang_revisions), error); } #ifndef STATIC diff --git a/src/plugins_exts/yang_revisions.c b/src/plugins_exts/yang_revisions.c new file mode 100644 index 000000000..8a90aa0e0 --- /dev/null +++ b/src/plugins_exts/yang_revisions.c @@ -0,0 +1,185 @@ +/** + * @file ang_revisions.c + * @author Joe Clarke + * @brief libyang extension plugin - YANG Revisions (ietf-yang-revisions) + * + * Copyright (c) 2025 Cisco Systems, Inc. + * + * This source code is licensed under BSD 3-Clause License (the "License"). + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + */ + +#include +#include +#include +#include + +#include "compat.h" +#include "libyang.h" +#include "plugins_exts.h" + +/** + * @brief Parse non-backwards-compatible extension instances. + * + * Implementation of ::lyplg_ext_parse_clb callback set as lyext_plugin::parse. + */ +static LY_ERR +non_backwards_compatible_parse(struct lysp_ctx *pctx, struct lysp_ext_instance *ext) +{ + struct lysp_revision *parent = NULL; + LY_ARRAY_COUNT_TYPE u; + + /* Check that the extension is instantiated at an allowed place - revision statement */ + if (ext->parent_stmt != LY_STMT_REVISION) { + lyplg_ext_parse_log(pctx, ext, LY_LLERR, LY_EVALID, + "Extension %s is allowed only in a revision statement, but it is placed in \"%s\" statement.", + ext->name, lyplg_ext_stmt2str(ext->parent_stmt)); + return LY_EVALID; + } + + /* This extension should not have an argument */ + if (ext->argument && *ext->argument) { + lyplg_ext_parse_log(pctx, ext, LY_LLWRN, 0, + "Extension %s should not have an argument, but has: %s", ext->name, ext->argument); + } + + parent = ext->parent; + + /* Check for duplication within the same revision */ + LY_ARRAY_FOR(parent->exts, u) { + if ((&parent->exts[u] != ext) && parent->exts[u].record && + !strcmp(parent->exts[u].record->plugin.id, ext->record->plugin.id)) { + lyplg_ext_parse_log(pctx, ext, LY_LLERR, LY_EVALID, + "Extension %s is instantiated multiple times in the same revision.", ext->name); + return LY_EVALID; + } + } + + return LY_SUCCESS; +} + +/** + * @brief Validate revision-date format (YYYY-MM-DD). + * + * @param[in] date Date string to validate. + * @return LY_SUCCESS if valid, LY_EVALID otherwise. + */ +static LY_ERR +revision_date_validate(const char *date) +{ + int year, month, day; + + if (!date || (strlen(date) != 10)) { + return LY_EVALID; + } + + if ((date[4] != '-') || (date[7] != '-')) { + return LY_EVALID; + } + + if (sscanf(date, "%4d-%2d-%2d", &year, &month, &day) != 3) { + return LY_EVALID; + } + + if ((year < 1000) || (year > 9999) || (month < 1) || (month > 12) || (day < 1) || (day > 31)) { + return LY_EVALID; + } + + return LY_SUCCESS; +} + +/** + * @brief Parse recommended-min-date extension instances. + * + * Implementation of ::lyplg_ext_parse_clb callback set as lyext_plugin::parse. + */ +static LY_ERR +recommended_min_date_parse(struct lysp_ctx *pctx, struct lysp_ext_instance *ext) +{ + struct lysp_import *parent = NULL; + LY_ARRAY_COUNT_TYPE u; + + /* Check that the extension is instantiated at an allowed place - import statement */ + if (ext->parent_stmt != LY_STMT_IMPORT) { + lyplg_ext_parse_log(pctx, ext, LY_LLERR, LY_EVALID, + "Extension %s is allowed only in an import statement, but it is placed in \"%s\" statement.", + ext->name, lyplg_ext_stmt2str(ext->parent_stmt)); + return LY_EVALID; + } + + /* Validate the argument format - must be revision-date (YYYY-MM-DD) */ + if (!ext->argument) { + lyplg_ext_parse_log(pctx, ext, LY_LLERR, LY_EVALID, + "Extension %s requires a revision-date argument (YYYY-MM-DD).", ext->name); + return LY_EVALID; + } + + if (revision_date_validate(ext->argument) != LY_SUCCESS) { + lyplg_ext_parse_log(pctx, ext, LY_LLERR, LY_EVALID, + "Extension %s has invalid revision-date format: %s (expected YYYY-MM-DD and a valid date)", + ext->name, ext->argument); + return LY_EVALID; + } + + parent = ext->parent; + + /* Check for duplication within the same import */ + LY_ARRAY_FOR(parent->exts, u) { + if ((&parent->exts[u] != ext) && parent->exts[u].record && + !strcmp(parent->exts[u].record->plugin.id, ext->record->plugin.id)) { + lyplg_ext_parse_log(pctx, ext, LY_LLERR, LY_EVALID, + "Extension %s is instantiated multiple times in the same import.", ext->name); + return LY_EVALID; + } + } + + return LY_SUCCESS; +} + +/** + * @brief Plugin descriptions for the ietf-yang-revisions extensions + * + * Note that external plugins are supposed to use: + * + * LYPLG_EXTENSIONS = { + */ +const struct lyplg_ext_record plugins_yang_revisions[] = { + { + .module = "ietf-yang-revisions", + .revision = "2025-01-28", + .name = "non-backwards-compatible", + + .plugin.id = "ly2 ietf-yang-revisions v1", + .plugin.parse = non_backwards_compatible_parse, + .plugin.compile = NULL, + .plugin.printer_info = NULL, + .plugin.printer_ctree = NULL, + .plugin.printer_ptree = NULL, + .plugin.node = NULL, + .plugin.snode = NULL, + .plugin.validate = NULL, + .plugin.pfree = NULL, + .plugin.cfree = NULL + }, + { + .module = "ietf-yang-revisions", + .revision = "2025-01-28", + .name = "recommended-min-date", + + .plugin.id = "ly2 ietf-yang-revisions v1", + .plugin.parse = recommended_min_date_parse, + .plugin.compile = NULL, + .plugin.printer_info = NULL, + .plugin.printer_ctree = NULL, + .plugin.printer_ptree = NULL, + .plugin.node = NULL, + .plugin.snode = NULL, + .plugin.validate = NULL, + .plugin.pfree = NULL, + .plugin.cfree = NULL + }, + {0} /* terminating zeroed record */ +}; diff --git a/src/plugins_exts/yang_semver.c b/src/plugins_exts/yang_semver.c new file mode 100644 index 000000000..022b6c93a --- /dev/null +++ b/src/plugins_exts/yang_semver.c @@ -0,0 +1,277 @@ +/** + * @file yang_semver.c + * @author Joe Clarke + * @brief libyang extension plugin - YANG Semantic Versioning (ietf-yang-semver) + * + * Copyright (c) 2025 Cisco Systems, Inc. + * + * This source code is licensed under BSD 3-Clause License (the "License"). + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + */ + +#include +#include +#include +#include + +#include "compat.h" +#include "libyang.h" +#include "plugins_exts.h" + +/** + * @brief Validate semantic version format (MAJOR.MINOR.PATCH with optional modifiers). + * + * @param[in] version Version string to validate. + * @param[in] allow_modifiers Whether to allow _compatible/_non_compatible and metadata. + * @return LY_SUCCESS if valid, LY_EVALID otherwise. + */ +static LY_ERR +semver_validate_format(const char *version, ly_bool allow_modifiers) +{ + const char *ptr = version; + int dots = 0; + int digits = 0; + + if (!version || !*version) { + return LY_EVALID; + } + + /* Parse MAJOR.MINOR.PATCH */ + while (*ptr) { + if (isdigit(*ptr)) { + digits++; + ptr++; + } else if (*ptr == '.') { + if ((digits == 0) || (dots >= 2)) { + return LY_EVALID; + } + dots++; + digits = 0; + ptr++; + } else { + /* Must be at modifier or metadata */ + break; + } + } + + /* Must have exactly 2 dots and digits after last dot */ + if ((dots != 2) || (digits == 0)) { + return LY_EVALID; + } + + /* For recommended-min-version, no modifiers allowed */ + if (!allow_modifiers && (*ptr != '\0')) { + return LY_EVALID; + } + + /* Optional: check for _compatible or _non_compatible */ + if (*ptr == '_') { + if (strncmp(ptr, "_compatible", 11) == 0) { + ptr += 11; + } else if (strncmp(ptr, "_non_compatible", 15) == 0) { + ptr += 15; + } else { + return LY_EVALID; + } + } + + /* Optional: check for pre-release version (dash followed by alphanumeric and dots/dashes) */ + if (*ptr == '-') { + ptr++; + if (!isalnum(*ptr)) { + return LY_EVALID; + } + while (*ptr && *ptr != '+') { + if (!isalnum(*ptr) && (*ptr != '.') && (*ptr != '-')) { + return LY_EVALID; + } + ptr++; + } + } + + /* Optional: check for metadata (plus followed by alphanumeric and dots/dashes) */ + if (*ptr == '+') { + ptr++; + if (!isalnum(*ptr)) { + return LY_EVALID; + } + while (*ptr) { + if (!isalnum(*ptr) && (*ptr != '.') && (*ptr != '-')) { + return LY_EVALID; + } + ptr++; + } + } + + return LY_SUCCESS; +} + +/** + * @brief Parse version extension instances. + * + * Implementation of ::lyplg_ext_parse_clb callback set as lyext_plugin::parse. + */ +static LY_ERR +version_parse(struct lysp_ctx *pctx, struct lysp_ext_instance *ext) +{ + const struct lysp_module *pmod; + LY_ARRAY_COUNT_TYPE u, v; + struct lysp_revision *rev; + const char *version_arg = ext->argument; + + /* Check that the extension is instantiated at an allowed place - revision statement */ + if (ext->parent_stmt != LY_STMT_REVISION) { + lyplg_ext_parse_log(pctx, ext, LY_LLERR, LY_EVALID, + "Extension %s is allowed only in a revision statement, but it is placed in \"%s\" statement.", + ext->name, lyplg_ext_stmt2str(ext->parent_stmt)); + return LY_EVALID; + } + + /* Validate the argument format */ + if (!ext->argument) { + lyplg_ext_parse_log(pctx, ext, LY_LLERR, LY_EVALID, + "Extension %s requires a YANG Semver argument.", ext->name); + return LY_EVALID; + } + + if (semver_validate_format(ext->argument, 1) != LY_SUCCESS) { + lyplg_ext_parse_log(pctx, ext, LY_LLERR, LY_EVALID, + "Extension %s has invalid YANG Semver version format: %s", ext->name, ext->argument); + return LY_EVALID; + } + + /* Get the module to check all revisions */ + pmod = lyplg_ext_parse_get_cur_pmod(pctx); + if (!pmod || !pmod->revs) { + return LY_SUCCESS; + } + + /* Check that this version is unique across all revisions */ + LY_ARRAY_FOR(pmod->revs, u) { + rev = &pmod->revs[u]; + if (!rev->exts) { + continue; + } + LY_ARRAY_FOR(rev->exts, v) { + /* Skip if this is the current extension instance */ + if (&rev->exts[v] == ext) { + continue; + } + + /* Check if this is also a version extension by name and module */ + if (rev->exts[v].name && !strcmp(rev->exts[v].name, ext->name) && + (rev->exts[v].parent_stmt == LY_STMT_REVISION)) { + /* Check for duplicate in same revision */ + if (rev->exts[v].parent == ext->parent) { + lyplg_ext_parse_log(pctx, ext, LY_LLERR, LY_EVALID, + "Extension %s is instantiated multiple times in the same revision.", ext->name); + return LY_EVALID; + } + /* Compare versions across different revisions */ + if (rev->exts[v].argument && !strcmp(rev->exts[v].argument, version_arg)) { + lyplg_ext_parse_log(pctx, ext, LY_LLERR, LY_EVALID, + "Version %s is not unique - it appears in multiple revisions.", version_arg); + return LY_EVALID; + } + } + } + } + + return LY_SUCCESS; +} + +/** + * @brief Parse recommended-min-version extension instances. + * + * Implementation of ::lyplg_ext_parse_clb callback set as lyext_plugin::parse. + */ +static LY_ERR +recommended_min_version_parse(struct lysp_ctx *pctx, struct lysp_ext_instance *ext) +{ + struct lysp_import *parent = NULL; + LY_ARRAY_COUNT_TYPE u; + + /* Check that the extension is instantiated at an allowed place - import statement */ + if (ext->parent_stmt != LY_STMT_IMPORT) { + lyplg_ext_parse_log(pctx, ext, LY_LLERR, LY_EVALID, + "Extension %s is allowed only in an import statement, but it is placed in \"%s\" statement.", + ext->name, lyplg_ext_stmt2str(ext->parent_stmt)); + return LY_EVALID; + } + + /* Validate the argument format - must be MAJOR.MINOR.PATCH only (no modifiers) */ + if (!ext->argument) { + lyplg_ext_parse_log(pctx, ext, LY_LLERR, LY_EVALID, + "Extension %s requires a MAJOR.MINOR.PATCH version argument.", ext->name); + return LY_EVALID; + } + + if (semver_validate_format(ext->argument, 0) != LY_SUCCESS) { + lyplg_ext_parse_log(pctx, ext, LY_LLERR, LY_EVALID, + "Extension %s argument must be MAJOR.MINOR.PATCH format (no modifiers): %s", + ext->name, ext->argument); + return LY_EVALID; + } + + parent = ext->parent; + + /* Check for duplication within the same import */ + LY_ARRAY_FOR(parent->exts, u) { + if ((&parent->exts[u] != ext) && parent->exts[u].record && + !strcmp(parent->exts[u].record->plugin.id, ext->record->plugin.id)) { + lyplg_ext_parse_log(pctx, ext, LY_LLERR, LY_EVALID, + "Extension %s is instantiated multiple times in the same import.", ext->name); + return LY_EVALID; + } + } + + return LY_SUCCESS; +} + +/** + * @brief Plugin descriptions for the ietf-yang-semver extensions + * + * Note that external plugins are supposed to use: + * + * LYPLG_EXTENSIONS = { + */ +const struct lyplg_ext_record plugins_yang_semver[] = { + { + .module = "ietf-yang-semver", + .revision = "2025-09-29", + .name = "version", + + .plugin.id = "ly2 ietf-yang-semver v1", + .plugin.parse = version_parse, + .plugin.compile = NULL, + .plugin.printer_info = NULL, + .plugin.printer_ctree = NULL, + .plugin.printer_ptree = NULL, + .plugin.node = NULL, + .plugin.snode = NULL, + .plugin.validate = NULL, + .plugin.pfree = NULL, + .plugin.cfree = NULL + }, + { + .module = "ietf-yang-semver", + .revision = "2025-09-29", + .name = "recommended-min-version", + + .plugin.id = "ly2 ietf-yang-semver v1", + .plugin.parse = recommended_min_version_parse, + .plugin.compile = NULL, + .plugin.printer_info = NULL, + .plugin.printer_ctree = NULL, + .plugin.printer_ptree = NULL, + .plugin.node = NULL, + .plugin.snode = NULL, + .plugin.validate = NULL, + .plugin.pfree = NULL, + .plugin.cfree = NULL + }, + {0} /* terminating zeroed record */ +}; diff --git a/tests/modules/yang/ietf-yang-revisions@2025-01-28.yang b/tests/modules/yang/ietf-yang-revisions@2025-01-28.yang new file mode 100644 index 000000000..eab4ae882 --- /dev/null +++ b/tests/modules/yang/ietf-yang-revisions@2025-01-28.yang @@ -0,0 +1,146 @@ +module ietf-yang-revisions { + yang-version 1.1; + namespace "urn:ietf:params:xml:ns:yang:ietf-yang-revisions"; + prefix rev; + + import ietf-yang-types { + prefix yang; + reference + "RFC YYYY-draft-ietf-netmod-rfc6991-bis: Common YANG Data Types"; + } + + organization + "IETF NETMOD (Network Modeling) Working Group"; + contact + "WG Web: + WG List: + + Author: Joe Clarke + + + Author: Reshad Rahman + + + Author: Robert Wilton + + + Author: Balazs Lengyel + + + Author: Jason Sterne + "; + description + "This YANG 1.1 module contains definitions and extensions to + support updated YANG revision handling. + + Copyright (c) 2024 IETF Trust and the persons identified as + authors of the code. All rights reserved. + + Redistribution and use in source and binary forms, with or + without modification, is permitted pursuant to, and subject to + the license terms contained in, the Revised BSD License set + forth in Section 4.c of the IETF Trust's Legal Provisions + Relating to IETF Documents + (https://trustee.ietf.org/license-info). + + This version of this YANG module is part of RFC XXXX; see + the RFC itself for full legal notices. + + The key words 'MUST', 'MUST NOT', 'REQUIRED', 'SHALL', 'SHALL + NOT', 'SHOULD', 'SHOULD NOT', 'RECOMMENDED', 'NOT RECOMMENDED', + 'MAY', and 'OPTIONAL' in this document are to be interpreted as + described in BCP 14 (RFC 2119) (RFC 8174) when, and only when, + they appear in all capitals, as shown here."; + // RFC Ed.: update the date below with the date of RFC publication + // and remove this note. + // RFC Ed.: replace XXXX (inc above) with actual RFC number and + // remove this note. + // RFC Ed.: replace YYYY-draft-ietf-netmod-rfc6991-bis (inc above) with actual RFC number and + // remove this note. + + revision 2025-01-28 { + description + "Initial version."; + reference + "RFC XXXX: Updated YANG Module Revision Handling"; + } + + typedef revision-date { + type yang:date-no-zone; + description + "A date associated with a YANG revision. + + Matches dates formatted as YYYY-MM-DD."; + reference + "RFC 7950: The YANG 1.1 Data Modeling Language"; + } + + extension non-backwards-compatible { + description + "This statement is used to indicate YANG module revisions that + contain non-backwards-compatible changes. + + The statement MUST only be a substatement of the 'revision' + statement. Zero or one 'non-backwards-compatible' statements + per parent statement is allowed. No substatements for this + extension have been standardized. + + If a revision of a YANG module contains changes, relative to + the preceding revision in the revision history, that do not + conform to the backwards-compatible module update rules + defined in RFC-XXXX, then the 'non-backwards-compatible' + statement MUST be added as a substatement to the revision + statement. + + Conversely, if a revision does not contain a + 'non-backwards-compatible' statement then all changes, + relative to the preceding revision in the revision history, + MUST be backwards-compatible. + + A new module revision that only contains changes that are + backwards-compatible SHOULD NOT include the + 'non-backwards-compatible' statement. An example of when an + author might add the 'non-backwards-compatible' statement is + if they believe a change could negatively impact clients even + though the backwards compatibility rules defined in RFC-XXXX + classify it as a backwards-compatible change. + + Add, removing, or changing a 'non-backwards-compatible' + statement is a backwards-compatible version change."; + reference + "XXXX: Updated YANG Module Revision Handling; + Section 3.2, + non-backwards-compatible extension statement"; + } + + extension recommended-min-date { + argument revision-date; + description + "Recommends the revision of the module that may be imported to + one whose revision date matches or is after the specified + revision-date. + + The argument value MUST conform to the 'revision-date' defined + type. + + The statement MUST only be a substatement of the import + statement. Zero, one or more 'recommended-min-date' + statements per parent statement are allowed. No substatements + for this extension have been standardized. + + Zero or one 'recommended-min-date' extension statement is + allowed for each parent 'import' statement. + + A particular revision of an imported module adheres to an + import's 'recommended-min-date' extension statement if the + imported module's revision date is equal to or later than + the revision date argument of the 'recommended-min-date' + extension statement in the importing module. + + Adding, removing or updating a 'recommended-min-date' + statement to an import is a backwards-compatible change."; + reference + "XXXX: Updated YANG Module Revision Handling; Section 4, + Guidance for revision selection on imports"; + } +} diff --git a/tests/modules/yang/ietf-yang-semver@2025-09-29.yang b/tests/modules/yang/ietf-yang-semver@2025-09-29.yang new file mode 100644 index 000000000..e68b202a8 --- /dev/null +++ b/tests/modules/yang/ietf-yang-semver@2025-09-29.yang @@ -0,0 +1,144 @@ +module ietf-yang-semver { + yang-version 1.1; + namespace "urn:ietf:params:xml:ns:yang:ietf-yang-semver"; + prefix ysv; + + organization + "IETF NETMOD (Network Modeling) Working Group"; + contact + "WG Web: + WG List: + + Author: Joe Clarke + + Author: Robert Wilton + + Author: Reshad Rahman + + Author: Balazs Lengyel + + Author: Jason Sterne + + Author: Benoit Claise + "; + description + "This module provides type and grouping definitions for YANG + packages. + + Copyright (c) 2025 IETF Trust and the persons identified as + authors of the code. All rights reserved. + + Redistribution and use in source and binary forms, with or + without modification, is permitted pursuant to, and subject + to the license terms contained in, the Revised BSD License + set forth in Section 4.c of the IETF Trust's Legal Provisions + Relating to IETF Documents + (http://trustee.ietf.org/license-info). + + The key words 'MUST', 'MUST NOT', 'REQUIRED', 'SHALL', 'SHALL + NOT', 'SHOULD', 'SHOULD NOT', 'RECOMMENDED', 'NOT RECOMMENDED', + 'MAY', and 'OPTIONAL' in this document are to be interpreted as + described in BCP 14 (RFC 2119) (RFC 8174) when, and only when, + they appear in all capitals, as shown here. + + This version of this YANG module is part of RFC XXXX; see + the RFC itself for full legal notices."; + + // RFC Ed.: update the date below with the date of RFC publication + // and remove this note. + // RFC Ed.: replace XXXX with actual RFC number and remove this + // note. + // RFC Ed. update the ysv:version to "1.0.0". + + revision 2025-09-29 { + ysv:version "0.24.0"; + description + "Initial revision"; + reference + "RFC XXXX: YANG Semantic Versioning."; + } + + /* + * Extensions + */ + + extension version { + argument yang-semantic-version; + description + "The version extension is used to assign a version number + to a module or submodule revision. + + The format of the version extension argument MUST conform + to the 'version' typedef defined in this module. + + The statement MUST only be a substatement of the revision + statement. Zero or one version statements per parent + statement are allowed. No substatements for this extension + have been standardized. + + Versions MUST be unique amongst all revisions of a + module or submodule. + + Adding, changing or removing a version is a + backwards-compatible change."; + reference + "RFC XXXX: YANG Semantic Versioning; + Section 4.2, YANG Semantic Version Extension"; + } + + extension recommended-min-version { + argument yang-semantic-version; + description + "Recommends the versions of the module that may be imported to + one that is greater than or equal to the specified version. + + The format of the recommended-min-version extension argument + must be the MAJOR.MINOR.PATCH components from the + 'version' typedef defined in this module (i.e., excluding + the '_compatible' and '_non_compatible' modifiers as + well as any metadata). + + The statement MUST only be a substatement of the import + statement. Zero or one 'recommended-min-version' + statements per parent statement are allowed. No + substatements for this extension have been + standardized. + + A module to be imported is considered as meeting the + recommended minimum version criteria if it meets one of + the following conditions: + + * Has the exact same MAJOR, MINOR, PATCH as in the + recommended-min-version value. + * Has the same MAJOR and MINOR version numbers and a + greater PATCH number. + * Has the same MAJOR version number and greater MINOR number. + In this case the PATCH number is ignored. + * Has a greater MAJOR version number. In this case MINOR + and PATCH numbers are ignored. + + Adding, removing or updating a 'recommended-min-version' + statement to an import is a backwards-compatible change."; + reference + "RFC XXXX: YANG Semantic Versioning; Section 5, + Import Module by Semantic Version"; + } + + /* + * Typedefs + */ + + typedef version { + type string { + length "5..128"; + pattern '[0-9]+[.][0-9]+[.][0-9]+(_(non_)?compatible)?' + + '(-[A-Za-z0-9.-]+[.-][0-9]+)?([+][A-Za-z0-9.-]+)?'; + } + description + "Represents a YANG semantic version. The rules governing the + use of this version identifier are defined in the + reference for this typedef."; + reference + "RFC XXXX: YANG Semantic Versioning."; + } +} diff --git a/tests/utests/CMakeLists.txt b/tests/utests/CMakeLists.txt index 46558e8ca..f656f4680 100644 --- a/tests/utests/CMakeLists.txt +++ b/tests/utests/CMakeLists.txt @@ -77,3 +77,5 @@ ly_add_utest(NAME nacm SOURCES extensions/test_nacm.c) ly_add_utest(NAME yangdata SOURCES extensions/test_yangdata.c) ly_add_utest(NAME schema_mount SOURCES extensions/test_schema_mount.c) ly_add_utest(NAME structure SOURCES extensions/test_structure.c) +ly_add_utest(NAME yang_revisions SOURCES extensions/test_yang_revisions.c) +ly_add_utest(NAME yang_semver SOURCES extensions/test_yang_semver.c) diff --git a/tests/utests/basic/test_context.c b/tests/utests/basic/test_context.c index 116b2ce36..4122d44ec 100644 --- a/tests/utests/basic/test_context.c +++ b/tests/utests/basic/test_context.c @@ -476,8 +476,9 @@ test_get_models(void **state) unsigned int index = 0; const char *names[] = { - "ietf-yang-metadata", "yang", "ietf-inet-types", "ietf-yang-types", "ietf-yang-schema-mount", - "ietf-yang-structure-ext", "ietf-datastores", "ietf-yang-library", "a", "a", "a" + "ietf-yang-metadata", "yang", "ietf-inet-types", "ietf-yang-types", "ietf-yang-semver", + "ietf-yang-revisions", "ietf-yang-schema-mount", "ietf-yang-structure-ext", "ietf-datastores", + "ietf-yang-library", "a", "a", "a" }; assert_int_equal(LY_SUCCESS, ly_in_new_memory(str0, &in0)); @@ -545,7 +546,7 @@ test_get_models(void **state) while ((mod = (struct lys_module *)ly_ctx_get_module_iter(UTEST_LYCTX, &index))) { assert_string_equal(names[index - 1], mod->name); } - assert_int_equal(11, index); + assert_int_equal(13, index); /* cleanup */ ly_in_free(in0, 0); diff --git a/tests/utests/extensions/test_yang_revisions.c b/tests/utests/extensions/test_yang_revisions.c new file mode 100644 index 000000000..4948e5e2f --- /dev/null +++ b/tests/utests/extensions/test_yang_revisions.c @@ -0,0 +1,148 @@ +/** + * @file test_yang_revisions.c + * @author Joe Clarke + * @brief unit tests for YANG Revisions extensions support + * + * Copyright (c) 2025 Cisco Systems, Inc. + * + * This source code is licensed under BSD 3-Clause License (the "License"). + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + */ +#define _UTEST_MAIN_ +#include "utests.h" + +#include "libyang.h" + +static int +setup(void **state) +{ + UTEST_SETUP; + + assert_int_equal(LY_SUCCESS, ly_ctx_set_searchdir(UTEST_LYCTX, TESTS_DIR_MODULES_YANG)); + assert_non_null(ly_ctx_load_module(UTEST_LYCTX, "ietf-yang-revisions", "2025-01-28", NULL)); + + return 0; +} + +static void +test_non_backwards_compatible_valid(void **state) +{ + struct lys_module *mod; + const char *data; + + /* Valid: no argument */ + data = "module a {yang-version 1.1; namespace urn:tests:extensions:revisions:a; prefix a;" + "import ietf-yang-revisions { prefix rev; }" + "revision 2025-01-01 { rev:non-backwards-compatible; }}"; + UTEST_ADD_MODULE(data, LYS_IN_YANG, NULL, &mod); +} + +static void +test_non_backwards_compatible_invalid(void **state) +{ + const char *data; + + /* Invalid: not in revision statement */ + data = "module a {yang-version 1.1; namespace urn:tests:extensions:revisions:a; prefix a;" + "import ietf-yang-revisions { prefix rev; }" + "rev:non-backwards-compatible;}"; + assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, data, LYS_IN_YANG, NULL)); + CHECK_LOG_CTX("Ext plugin \"ly2 ietf-yang-revisions v1\": " + "Extension rev:non-backwards-compatible is allowed only in a revision statement, but it is placed in \"module\" statement.", + "/a:{extension='rev:non-backwards-compatible'}", 0); + + /* Invalid: duplicate in same revision */ + data = "module c {yang-version 1.1; namespace urn:tests:extensions:revisions:c; prefix c;" + "import ietf-yang-revisions { prefix rev; }" + "revision 2025-01-01 { rev:non-backwards-compatible; rev:non-backwards-compatible; }}"; + assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, data, LYS_IN_YANG, NULL)); + CHECK_LOG_CTX("Ext plugin \"ly2 ietf-yang-revisions v1\": " + "Extension rev:non-backwards-compatible is instantiated multiple times in the same revision.", + "/c:{extension='rev:non-backwards-compatible'}", 0); +} + +static void +test_recommended_min_date_valid(void **state) +{ + struct lys_module *mod; + const char *data; + + /* Valid: proper date format */ + data = "module a {yang-version 1.1; namespace urn:tests:extensions:revisions:a; prefix a;" + "import ietf-yang-revisions { prefix rev; }" + "import ietf-yang-types { prefix yt; rev:recommended-min-date \"2013-07-15\"; }}"; + UTEST_ADD_MODULE(data, LYS_IN_YANG, NULL, &mod); + + /* Valid: different date */ + data = "module b {yang-version 1.1; namespace urn:tests:extensions:revisions:b; prefix b;" + "import ietf-yang-revisions { prefix rev; }" + "import ietf-yang-types { prefix yt; rev:recommended-min-date \"2020-12-31\"; }}"; + UTEST_ADD_MODULE(data, LYS_IN_YANG, NULL, &mod); +} + +static void +test_recommended_min_date_invalid(void **state) +{ + const char *data; + + /* Invalid: not in import statement */ + data = "module a {yang-version 1.1; namespace urn:tests:extensions:revisions:a; prefix a;" + "import ietf-yang-revisions { prefix rev; }" + "rev:recommended-min-date \"2013-07-15\";}"; + assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, data, LYS_IN_YANG, NULL)); + CHECK_LOG_CTX("Ext plugin \"ly2 ietf-yang-revisions v1\": " + "Extension rev:recommended-min-date is allowed only in an import statement, but it is placed in \"module\" statement.", + "/a:{extension='rev:recommended-min-date'}/2013-07-15", 0); + + /* Invalid: bad date format - wrong separator */ + data = "module b {yang-version 1.1; namespace urn:tests:extensions:revisions:b; prefix b;" + "import ietf-yang-revisions { prefix rev; }" + "import ietf-yang-types { prefix yt; rev:recommended-min-date \"2013/07/15\"; }}"; + assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, data, LYS_IN_YANG, NULL)); + CHECK_LOG_CTX("Ext plugin \"ly2 ietf-yang-revisions v1\": " + "Extension rev:recommended-min-date has invalid revision-date format: 2013/07/15 (expected YYYY-MM-DD and a valid date)", + "/b:{extension='rev:recommended-min-date'}/2013/07/15", 0); + + /* Invalid: bad date format - too short */ + data = "module c {yang-version 1.1; namespace urn:tests:extensions:revisions:c; prefix c;" + "import ietf-yang-revisions { prefix rev; }" + "import ietf-yang-types { prefix yt; rev:recommended-min-date \"2013-07\"; }}"; + assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, data, LYS_IN_YANG, NULL)); + CHECK_LOG_CTX("Ext plugin \"ly2 ietf-yang-revisions v1\": " + "Extension rev:recommended-min-date has invalid revision-date format: 2013-07 (expected YYYY-MM-DD and a valid date)", + "/c:{extension='rev:recommended-min-date'}/2013-07", 0); + + /* Invalid: bad date - invalid month */ + data = "module d {yang-version 1.1; namespace urn:tests:extensions:revisions:d; prefix d;" + "import ietf-yang-revisions { prefix rev; }" + "import ietf-yang-types { prefix yt; rev:recommended-min-date \"2013-13-15\"; }}"; + assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, data, LYS_IN_YANG, NULL)); + CHECK_LOG_CTX("Ext plugin \"ly2 ietf-yang-revisions v1\": " + "Extension rev:recommended-min-date has invalid revision-date format: 2013-13-15 (expected YYYY-MM-DD and a valid date)", + "/d:{extension='rev:recommended-min-date'}/2013-13-15", 0); + + /* Invalid: duplicate in same import */ + data = "module e {yang-version 1.1; namespace urn:tests:extensions:revisions:e; prefix e;" + "import ietf-yang-revisions { prefix rev; }" + "import ietf-yang-types { prefix yt; rev:recommended-min-date \"2013-07-15\"; rev:recommended-min-date \"2014-01-01\"; }}"; + assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, data, LYS_IN_YANG, NULL)); + CHECK_LOG_CTX("Ext plugin \"ly2 ietf-yang-revisions v1\": " + "Extension rev:recommended-min-date is instantiated multiple times in the same import.", + "/e:{extension='rev:recommended-min-date'}/2013-07-15", 0); +} + +int +main(void) +{ + const struct CMUnitTest tests[] = { + UTEST(test_non_backwards_compatible_valid, setup), + UTEST(test_non_backwards_compatible_invalid, setup), + UTEST(test_recommended_min_date_valid, setup), + UTEST(test_recommended_min_date_invalid, setup), + }; + + return cmocka_run_group_tests(tests, NULL, NULL); +} diff --git a/tests/utests/extensions/test_yang_semver.c b/tests/utests/extensions/test_yang_semver.c new file mode 100644 index 000000000..fcc43db56 --- /dev/null +++ b/tests/utests/extensions/test_yang_semver.c @@ -0,0 +1,212 @@ +/** + * @file test_yang_semver.c + * @author Joe Clarke + * @brief unit tests for YANG Semantic Versioning extensions support + * + * Copyright (c) 2025 Cisco Systems, Inc. + * + * This source code is licensed under BSD 3-Clause License (the "License"). + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + */ +#define _UTEST_MAIN_ +#include "utests.h" + +#include "libyang.h" + +static int +setup(void **state) +{ + UTEST_SETUP; + + assert_int_equal(LY_SUCCESS, ly_ctx_set_searchdir(UTEST_LYCTX, TESTS_DIR_MODULES_YANG)); + assert_non_null(ly_ctx_load_module(UTEST_LYCTX, "ietf-yang-semver", "2025-09-29", NULL)); + + return 0; +} + +static void +test_version_valid(void **state) +{ + struct lys_module *mod; + const char *data; + + /* Valid: basic semantic version */ + data = "module a {yang-version 1.1; namespace urn:tests:extensions:semver:a; prefix a;" + "import ietf-yang-semver { prefix ysv; }" + "revision 2025-01-01 { ysv:version \"1.0.0\"; }}"; + UTEST_ADD_MODULE(data, LYS_IN_YANG, NULL, &mod); + + /* Valid: version with compatible modifier */ + data = "module b {yang-version 1.1; namespace urn:tests:extensions:semver:b; prefix b;" + "import ietf-yang-semver { prefix ysv; }" + "revision 2025-01-01 { ysv:version \"1.0.0_compatible\"; }}"; + UTEST_ADD_MODULE(data, LYS_IN_YANG, NULL, &mod); + + /* Valid: version with non_compatible modifier */ + data = "module c {yang-version 1.1; namespace urn:tests:extensions:semver:c; prefix c;" + "import ietf-yang-semver { prefix ysv; }" + "revision 2025-01-01 { ysv:version \"2.1.3_non_compatible\"; }}"; + UTEST_ADD_MODULE(data, LYS_IN_YANG, NULL, &mod); + + /* Valid: version with pre-release */ + data = "module d {yang-version 1.1; namespace urn:tests:extensions:semver:d; prefix d;" + "import ietf-yang-semver { prefix ysv; }" + "revision 2025-01-01 { ysv:version \"1.0.0-alpha.1\"; }}"; + UTEST_ADD_MODULE(data, LYS_IN_YANG, NULL, &mod); + + /* Valid: version with metadata */ + data = "module e {yang-version 1.1; namespace urn:tests:extensions:semver:e; prefix e;" + "import ietf-yang-semver { prefix ysv; }" + "revision 2025-01-01 { ysv:version \"1.0.0+build.123\"; }}"; + UTEST_ADD_MODULE(data, LYS_IN_YANG, NULL, &mod); + + /* Valid: complex version */ + data = "module f {yang-version 1.1; namespace urn:tests:extensions:semver:f; prefix f;" + "import ietf-yang-semver { prefix ysv; }" + "revision 2025-01-01 { ysv:version \"1.2.3_compatible-beta.2+build.456\"; }}"; + UTEST_ADD_MODULE(data, LYS_IN_YANG, NULL, &mod); +} + +static void +test_version_invalid(void **state) +{ + const char *data; + + /* Invalid: not in revision statement */ + data = "module a {yang-version 1.1; namespace urn:tests:extensions:semver:a; prefix a;" + "import ietf-yang-semver { prefix ysv; }" + "ysv:version \"1.0.0\";}"; + assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, data, LYS_IN_YANG, NULL)); + CHECK_LOG_CTX("Ext plugin \"ly2 ietf-yang-semver v1\": " + "Extension ysv:version is allowed only in a revision statement, but it is placed in \"module\" statement.", + "/a:{extension='ysv:version'}/1.0.0", 0); + + /* Invalid: bad format - missing patch */ + data = "module c {yang-version 1.1; namespace urn:tests:extensions:semver:c; prefix c;" + "import ietf-yang-semver { prefix ysv; }" + "revision 2025-01-01 { ysv:version \"1.0\"; }}"; + assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, data, LYS_IN_YANG, NULL)); + CHECK_LOG_CTX("Ext plugin \"ly2 ietf-yang-semver v1\": " + "Extension ysv:version has invalid YANG Semver version format: 1.0", + "/c:{extension='ysv:version'}/1.0", 0); + + /* Invalid: bad format - too many dots */ + data = "module d {yang-version 1.1; namespace urn:tests:extensions:semver:d; prefix d;" + "import ietf-yang-semver { prefix ysv; }" + "revision 2025-01-01 { ysv:version \"1.0.0.1\"; }}"; + assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, data, LYS_IN_YANG, NULL)); + CHECK_LOG_CTX("Ext plugin \"ly2 ietf-yang-semver v1\": " + "Extension ysv:version has invalid YANG Semver version format: 1.0.0.1", + "/d:{extension='ysv:version'}/1.0.0.1", 0); + + /* Invalid: duplicate in same revision */ + data = "module e {yang-version 1.1; namespace urn:tests:extensions:semver:e; prefix e;" + "import ietf-yang-semver { prefix ysv; }" + "revision 2025-01-01 { ysv:version \"1.0.0\"; ysv:version \"1.0.1\"; }}"; + assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, data, LYS_IN_YANG, NULL)); + CHECK_LOG_CTX("Ext plugin \"ly2 ietf-yang-semver v1\": " + "Extension ysv:version is instantiated multiple times in the same revision.", + "/e:{extension='ysv:version'}/1.0.0", 0); +} + +static void +test_version_uniqueness(void **state) +{ + struct lys_module *mod; + const char *data; + + /* Invalid: same version in different revisions */ + data = "module a {yang-version 1.1; namespace urn:tests:extensions:semver:a; prefix a;" + "import ietf-yang-semver { prefix ysv; }" + "revision 2025-01-01 { ysv:version \"1.0.0\"; }" + "revision 2025-02-01 { ysv:version \"1.0.0\"; }}"; + assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, data, LYS_IN_YANG, NULL)); + CHECK_LOG_CTX("Ext plugin \"ly2 ietf-yang-semver v1\": " + "Version 1.0.0 is not unique - it appears in multiple revisions.", + "/a:{extension='ysv:version'}/1.0.0", 0); + + /* Valid: different versions in different revisions */ + data = "module b {yang-version 1.1; namespace urn:tests:extensions:semver:b; prefix b;" + "import ietf-yang-semver { prefix ysv; }" + "revision 2025-01-01 { ysv:version \"1.0.0\"; }" + "revision 2025-02-01 { ysv:version \"1.0.1\"; }}"; + UTEST_ADD_MODULE(data, LYS_IN_YANG, NULL, &mod); +} + +static void +test_recommended_min_version_valid(void **state) +{ + struct lys_module *mod; + const char *data; + + /* Valid: basic MAJOR.MINOR.PATCH */ + data = "module a {yang-version 1.1; namespace urn:tests:extensions:semver:a; prefix a;" + "import ietf-yang-semver { prefix ysv; }" + "import ietf-yang-types { prefix yt; ysv:recommended-min-version \"1.0.0\"; }}"; + UTEST_ADD_MODULE(data, LYS_IN_YANG, NULL, &mod); + + /* Valid: different version format */ + data = "module b {yang-version 1.1; namespace urn:tests:extensions:semver:b; prefix b;" + "import ietf-yang-semver { prefix ysv; }" + "import ietf-yang-types { prefix yt; ysv:recommended-min-version \"2.15.3\"; }}"; + UTEST_ADD_MODULE(data, LYS_IN_YANG, NULL, &mod); +} + +static void +test_recommended_min_version_invalid(void **state) +{ + const char *data; + + /* Invalid: not in import statement */ + data = "module a {yang-version 1.1; namespace urn:tests:extensions:semver:a; prefix a;" + "import ietf-yang-semver { prefix ysv; }" + "ysv:recommended-min-version \"1.0.0\";}"; + assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, data, LYS_IN_YANG, NULL)); + CHECK_LOG_CTX("Ext plugin \"ly2 ietf-yang-semver v1\": " + "Extension ysv:recommended-min-version is allowed only in an import statement, but it is placed in \"module\" statement.", + "/a:{extension='ysv:recommended-min-version'}/1.0.0", 0); + + /* Invalid: has modifiers (not allowed) */ + data = "module b {yang-version 1.1; namespace urn:tests:extensions:semver:b; prefix b;" + "import ietf-yang-semver { prefix ysv; }" + "import ietf-yang-types { prefix yt; ysv:recommended-min-version \"1.0.0_compatible\"; }}"; + assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, data, LYS_IN_YANG, NULL)); + CHECK_LOG_CTX("Ext plugin \"ly2 ietf-yang-semver v1\": " + "Extension ysv:recommended-min-version argument must be MAJOR.MINOR.PATCH format (no modifiers): 1.0.0_compatible", + "/b:{extension='ysv:recommended-min-version'}/1.0.0_compatible", 0); + + /* Invalid: has pre-release (not allowed) */ + data = "module c {yang-version 1.1; namespace urn:tests:extensions:semver:c; prefix c;" + "import ietf-yang-semver { prefix ysv; }" + "import ietf-yang-types { prefix yt; ysv:recommended-min-version \"1.0.0-alpha\"; }}"; + assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, data, LYS_IN_YANG, NULL)); + CHECK_LOG_CTX("Ext plugin \"ly2 ietf-yang-semver v1\": " + "Extension ysv:recommended-min-version argument must be MAJOR.MINOR.PATCH format (no modifiers): 1.0.0-alpha", + "/c:{extension='ysv:recommended-min-version'}/1.0.0-alpha", 0); + + /* Invalid: duplicate in same import */ + data = "module d {yang-version 1.1; namespace urn:tests:extensions:semver:d; prefix d;" + "import ietf-yang-semver { prefix ysv; }" + "import ietf-yang-types { prefix yt; ysv:recommended-min-version \"1.0.0\"; ysv:recommended-min-version \"2.0.0\"; }}"; + assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, data, LYS_IN_YANG, NULL)); + CHECK_LOG_CTX("Ext plugin \"ly2 ietf-yang-semver v1\": " + "Extension ysv:recommended-min-version is instantiated multiple times in the same import.", + "/d:{extension='ysv:recommended-min-version'}/1.0.0", 0); +} + +int +main(void) +{ + const struct CMUnitTest tests[] = { + UTEST(test_version_valid, setup), + UTEST(test_version_invalid, setup), + UTEST(test_version_uniqueness, setup), + UTEST(test_recommended_min_version_valid, setup), + UTEST(test_recommended_min_version_invalid, setup), + }; + + return cmocka_run_group_tests(tests, NULL, NULL); +}