Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
stmt.i_module.i_version == '1' and stmt.arg != 'bits')):
err_add(ctx.errors, bits[0].pos, 'BAD_RESTRICTION', 'bit')
elif stmt.arg == 'bits' and not bits:
err_add(ctx.errors, stmt.pos, 'MISSING_TYPE_SPEC',
('bits', 'bit'))
elif bits:
stmt.i_is_derived = True
bit_spec = types.validate_bits(ctx.errors, bits, stmt)
if bit_spec is not None:
stmt.i_type_spec = types.BitTypeSpec(stmt.i_type_spec,
bit_spec)
# check the union types
membertypes = stmt.search('type')
if membertypes and stmt.arg != 'union':
err_add(ctx.errors, membertypes[0].pos, 'BAD_RESTRICTION', 'union')
elif not membertypes and stmt.arg == 'union':
err_add(ctx.errors, stmt.pos, 'MISSING_TYPE_SPEC',
('union', 'type'))
elif membertypes:
stmt.i_is_derived = True
for t in membertypes:
if t.is_grammatically_valid is True:
v_type_type(ctx, t)
stmt.i_type_spec = types.UnionTypeSpec(membertypes)
if stmt.i_module.i_version == '1':
t = has_type(stmt, ['empty', 'leafref'])
if t is not None:
err_add(ctx.errors, stmt.pos, 'BAD_TYPE_IN_UNION',
(t.arg, t.pos))
return False
del t.parent.substmts[idx]
elif stmt.arg == 'add':
for c in stmt.substmts:
if c.keyword == '_comment':
continue
if c.keyword == 'config' and hasattr(t, 'i_config'):
# config is special: since it is an inherited property
# with a default, all nodes has a config property.
config = t.search_one(c.keyword)
if config is None:
if c.arg == 'true':
if (t.parent is None
or t.parent.i_config is True):
t.substmts.append(c)
else:
err_add(ctx.errors, c.pos,
'INVALID_CONFIG', ())
continue
else:
if not search_children_config_true(t, t):
t.substmts.append(c)
else:
err_add(ctx.errors, c.pos, 'BAD_DEVIATE_ADD',
(c.keyword, t.i_module.arg, t.arg))
elif c.keyword in _singleton_keywords:
if t.search_one(c.keyword) is not None:
err_add(ctx.errors, c.pos, 'BAD_DEVIATE_ADD',
(c.keyword, t.i_module.arg, t.arg))
elif t.keyword not in _valid_deviations[c.keyword]:
err_add(ctx.errors, c.pos, 'BAD_DEVIATE_TYPE',
c.keyword)
if stmt.keyword == 'module':
submodule.i_including_modulename = stmt.arg
else:
submodule.i_including_modulename = mymodulename
b = submodule.search_one('belongs-to')
if b is not None and b.arg != mymodulename:
err_add(ctx.errors, b.pos,
'BAD_SUB_BELONGS_TO',
(stmt.arg, submodule.arg, submodule.arg))
else:
# check that each submodule included by this submodule
# is also included by the module
if stmt.keyword == 'module':
for s in submodule.search('include'):
if stmt.search_one('include', s.arg) is None:
err_add(ctx.errors, s.pos,
'MISSING_INCLUDE',
(s.arg, submodule.arg, stmt.arg))
# add typedefs, groupings, nodes etc to this module
for ch in submodule.i_children:
if ch not in stmt.i_children:
stmt.i_children.append(ch)
# verify that the submodule's definitions do not collide
# with the module's definitions
defs = [
(submodule.i_typedefs, stmt.i_typedefs,
'TYPE_ALREADY_DEFINED'),
(submodule.i_groupings, stmt.i_groupings,
'GROUPING_ALREADY_DEFINED'),
(submodule.i_features, stmt.i_features,
'FEATURE_ALREADY_DEFINED'),
def chk_mandatory(s):
if s.keyword == 'leaf':
m = s.search_one('mandatory')
if m is not None and m.arg == 'true':
err_add(ctx.errors, m.pos, 'AUGMENT_MANDATORY', s.arg)
elif s.keyword == 'list' or s.keyword == 'leaf-list':
m = s.search_one('min-elements')
if m is not None and m.arg.isnumeric() and int(m.arg) >= 1:
err_add(ctx.errors, m.pos, 'AUGMENT_MANDATORY', s.arg)
elif s.keyword == 'container':
p = s.search_one('presence')
if p is None:
for sc in s.i_children:
chk_mandatory(sc)
# if we're augmenting another module, make sure we're not
err_add(ctx.errors, u.pos, 'BAD_UNIQUE', expr)
return
if ptr in found:
err_add(ctx.errors, u.pos, 'DUPLICATE_UNIQUE', expr)
if hasattr(ptr, 'i_config'):
if uconfig is None:
uconfig = ptr.i_config
elif uconfig != ptr.i_config:
err_add(ctx.errors, u.pos, 'BAD_UNIQUE_CONFIG', expr)
return
# add this unique statement to ptr's list of unique conditions
# it is part of.
ptr.i_uniques.append(u)
found.append(ptr)
if not found:
err_add(ctx.errors, u.pos, 'BAD_UNIQUE', u.arg)
return
# check if all leafs in the unique statements are keys
if len(list(stmt.i_key)) > 0:
key = list(stmt.i_key)
for f in found:
if f in key:
key.remove(f)
if len(key) == 0:
err_add(ctx.errors, u.pos, 'UNIQUE_IS_KEY', ())
u.i_leafs = found
stmt.i_unique.append((u, found))
def v_type_typedef(ctx, stmt):
if hasattr(stmt, 'i_is_validated'):
if stmt.i_is_validated == True:
# this type has already been validated
return
elif stmt.i_is_circular == True:
return
elif stmt.i_is_validated == 'in_progress':
err_add(ctx.errors, stmt.pos,
'CIRCULAR_DEPENDENCY', ('type', stmt.arg) )
stmt.i_is_circular = True
return
stmt.i_is_circular = False
stmt.i_is_validated = 'in_progress'
stmt.i_default = None
stmt.i_default_str = ""
stmt.i_is_unused = True
stmt.i_leafref = None # path_type_spec
stmt.i_leafref_ptr = None # pointer to the leaf the leafref refer to
stmt.i_leafref_expanded = False
name = stmt.arg
if stmt.parent.parent is not None:
if stmt.i_type_spec is not None:
stmt.i_type_spec.definition = ('at ' +
str(stmt.i_typedef.pos) +
' ')
if stmt.i_type_spec is None:
# an error has been added already; skip further validation
return
# check the fraction-digits - only applicable when the type is the builtin
# decimal64
frac = stmt.search_one('fraction-digits')
if frac is not None and stmt.arg != 'decimal64':
err_add(ctx.errors, frac.pos, 'BAD_RESTRICTION', 'fraction_digits')
elif stmt.arg == 'decimal64' and frac is None:
err_add(ctx.errors, stmt.pos, 'MISSING_TYPE_SPEC_1',
('decimal64', 'fraction-digits'))
elif stmt.arg == 'decimal64' and frac.is_grammatically_valid:
stmt.i_is_derived = True
stmt.i_type_spec = types.Decimal64TypeSpec(frac)
# check the range restriction
stmt.i_ranges = []
range = stmt.search_one('range')
if (range is not None and
'range' not in stmt.i_type_spec.restrictions()):
err_add(ctx.errors, range.pos, 'BAD_RESTRICTION', 'range')
elif range is not None:
stmt.i_is_derived = True
ranges_spec = types.validate_range_expr(ctx.errors, range, stmt)
if ranges_spec is not None:
stmt.i_ranges = ranges_spec[0]
def v_type_if_feature(ctx, stmt, no_error_report=False):
"""verify that the referenced feature exists."""
stmt.i_feature = None
# Verify the argument type
expr = syntax.parse_if_feature_expr(stmt.arg)
if stmt.i_module.i_version == '1':
# version 1 allows only a single value as if-feature
if type(expr) != type(''):
err_add(ctx.errors, stmt.pos,
'BAD_VALUE', (stmt.arg, 'identifier-ref'))
return
def eval(expr):
if type(expr) == type(''):
return has_feature(expr)
else:
(op, op1, op2) = expr
if op == 'not':
return not eval(op1)
elif op == 'and':
return eval(op1) and eval(op2)
elif op == 'or':
return eval(op1) or eval(op2)
def has_feature(name):
stmt.i_is_circular = False
stmt.i_is_validated = 'in_progress'
stmt.i_default = None
stmt.i_default_str = ""
stmt.i_is_unused = True
stmt.i_leafref = None # path_type_spec
stmt.i_leafref_ptr = None # pointer to the leaf the leafref refer to
stmt.i_leafref_expanded = False
name = stmt.arg
if stmt.parent.parent is not None:
# non-top-level typedef; check if it is already defined
ptype = search_typedef(stmt.parent.parent, name)
if ptype is not None:
err_add(ctx.errors, stmt.pos, 'TYPE_ALREADY_DEFINED',
(name, ptype.pos))
type_ = stmt.search_one('type')
if type_ is None or type_.is_grammatically_valid == False:
# error is already reported by grammar check
return
# ensure our type is validated
v_type_type(ctx, type_)
# keep track of our leafref
type_spec = type_.i_type_spec
if type(type_spec) == types.PathTypeSpec:
stmt.i_leafref = type_spec
def check_circular_typedef(ctx, type_):
# ensure the type is validated
v_type_type(ctx, type_)
stmt.i_is_derived = True
if path.is_grammatically_valid == True:
path_spec = types.validate_path_expr(ctx.errors, path)
if path_spec is not None:
stmt.i_type_spec = types.PathTypeSpec(stmt.i_type_spec,
path_spec, path, path.pos)
stmt.i_type_spec.i_source_stmt = stmt
# check the base restriction
bases = stmt.search('base')
if bases != [] and stmt.arg != 'identityref':
err_add(ctx.errors, bases[0].pos, 'BAD_RESTRICTION', 'base')
elif len(bases) > 1 and stmt.i_module.i_version == '1':
err_add(ctx.errors, bases[1].pos, 'UNEXPECTED_KEYWORD', 'base')
elif stmt.arg == 'identityref' and bases == []:
err_add(ctx.errors, stmt.pos, 'MISSING_TYPE_SPEC',
('identityref', 'base'))
else:
idbases = []
for base in bases:
v_type_base(ctx, base)
if base.i_identity is not None:
idbases.append(base)
if len(idbases) > 0:
stmt.i_is_derived = True
stmt.i_type_spec = types.IdentityrefTypeSpec(idbases)
# check the require-instance restriction
req_inst = stmt.search_one('require-instance')
if (req_inst is not None and
'require-instance' not in stmt.i_type_spec.restrictions()):
err_add(ctx.errors, req_inst.pos, 'BAD_RESTRICTION', 'require-instance')