Skip to content

Commit 0f43838

Browse files
stewegsamuel-gauthier
authored andcommitted
schema: add Pattern class
This patches introduces a new Pattern class that represents a pattern statement. A new pattern_details method is added to access the pattern statements of a node. Fixes: #92 Signed-off-by: Stefan Gula <steweg@gmail.com> Signed-off-by: Samuel Gauthier <samuel.gauthier@6wind.com>
1 parent f5b4e7a commit 0f43838

File tree

5 files changed

+66
-1
lines changed

5 files changed

+66
-1
lines changed

cffi/cdefs.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -792,6 +792,21 @@ struct lysc_must {
792792
struct lysc_ext_instance *exts;
793793
};
794794

795+
struct pcre2_real_code;
796+
typedef struct pcre2_real_code pcre2_code;
797+
798+
struct lysc_pattern {
799+
const char *expr;
800+
pcre2_code *code;
801+
const char *dsc;
802+
const char *ref;
803+
const char *emsg;
804+
const char *eapptag;
805+
struct lysc_ext_instance *exts;
806+
uint32_t inverted : 1;
807+
uint32_t refcount : 31;
808+
};
809+
795810
#define LYSP_RESTR_PATTERN_ACK ...
796811
#define LYSP_RESTR_PATTERN_NACK ...
797812

libyang/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@
7575
IfOrFeatures,
7676
Module,
7777
Must,
78+
Pattern,
7879
Revision,
7980
SContainer,
8081
SLeaf,
@@ -146,6 +147,7 @@
146147
"NodeTypeRemoved",
147148
"OrderedByUserAdded",
148149
"OrderedByUserRemoved",
150+
"Pattern",
149151
"PatternAdded",
150152
"PatternRemoved",
151153
"PresenceAdded",

libyang/schema.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,24 @@ class Bit(_EnumBit):
448448
pass
449449

450450

451+
# -------------------------------------------------------------------------------------
452+
class Pattern:
453+
__slots__ = ("context", "cdata")
454+
455+
def __init__(self, context: "libyang.Context", cdata):
456+
self.context = context
457+
self.cdata = cdata # C type: "struct lysc_pattern *"
458+
459+
def expression(self) -> str:
460+
return c2str(self.cdata.expr)
461+
462+
def inverted(self) -> bool:
463+
return self.cdata.inverted
464+
465+
def error_message(self) -> Optional[str]:
466+
return c2str(self.cdata.emsg) if self.cdata.emsg != ffi.NULL else None
467+
468+
451469
# -------------------------------------------------------------------------------------
452470
class Type:
453471
__slots__ = ("context", "cdata", "cdata_parsed", "__dict__")
@@ -681,6 +699,24 @@ def all_patterns(self) -> Iterator[Tuple[str, bool]]:
681699
else:
682700
yield from self.patterns()
683701

702+
def pattern_details(self) -> Iterator[Pattern]:
703+
if self.cdata.basetype != self.STRING:
704+
return
705+
t = ffi.cast("struct lysc_type_str *", self.cdata)
706+
if t.patterns == ffi.NULL:
707+
return
708+
for p in ly_array_iter(t.patterns):
709+
if not p:
710+
continue
711+
yield Pattern(self.context, p)
712+
713+
def all_pattern_details(self) -> Iterator[Pattern]:
714+
if self.cdata.basetype == lib.LY_TYPE_UNION:
715+
for t in self.union_types():
716+
yield from t.all_pattern_details()
717+
else:
718+
yield from self.pattern_details()
719+
684720
def require_instance(self) -> Optional[bool]:
685721
if self.cdata.basetype != self.LEAFREF:
686722
return None

tests/test_schema.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
LibyangError,
1414
Module,
1515
Must,
16+
Pattern,
1617
Revision,
1718
SContainer,
1819
SLeaf,
@@ -439,6 +440,15 @@ def test_leaf_type_pattern(self):
439440
t = leaf.type()
440441
self.assertIsInstance(t, Type)
441442
self.assertEqual(list(t.patterns()), [("[a-z.]+", False), ("1", True)])
443+
patterns = list(t.all_pattern_details())
444+
self.assertEqual(len(patterns), 2)
445+
self.assertIsInstance(patterns[0], Pattern)
446+
self.assertEqual(patterns[0].expression(), "[a-z.]+")
447+
self.assertFalse(patterns[0].inverted())
448+
self.assertEqual(patterns[0].error_message(), "ERROR1")
449+
self.assertEqual(patterns[1].expression(), "1")
450+
self.assertTrue(patterns[1].inverted())
451+
self.assertIsNone(patterns[1].error_message())
442452

443453
def test_leaf_type_union(self):
444454
leaf = next(self.ctx.find_path("/yolo-system:conf/yolo-system:number"))

tests/yang/yolo/yolo-system.yang

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,9 @@ module yolo-system {
8585
}
8686
leaf host {
8787
type string {
88-
pattern "[a-z.]+";
88+
pattern "[a-z.]+" {
89+
error-message "ERROR1";
90+
}
8991
pattern "1" {
9092
modifier "invert-match";
9193
}

0 commit comments

Comments
 (0)