def validate(self, errors, pos, val, errstr = ''):
     if util.keysearch(val, 0, self.enums) == None:
         err_add(errors, pos, 'TYPE_VALUE',
                 (val, self.definition, 'enum not defined' + errstr))
         return False
     else:
         return True
 def validate(self, errors, pos, val, errstr = ''):
     for v in val:
         if util.keysearch(v, 0, self.bits) == None:
             err_add(errors, pos, 'TYPE_VALUE',
                     (v, self.definition, 'bit not defined' + errstr))
             return False
     return True
    def get_keyword(self):
        """ret: identifier | (prefix, identifier)"""
        self.skip()

        m = syntax.re_keyword.match(self.buf)
        if m == None:
            error.err_add(self.errors, self.pos,
                          'SYNTAX_ERROR', 'illegal keyword: ' + self.buf)
            raise error.Abort
        else:
            self.set_buf(m.end())
            # check the separator
            if (self.buf[0].isspace() or
                (self.buf[0] == '/' and self.buf[1] in ('/', '*')) or
                (self.buf[0] in (';','{'))):
                pass
            else:
                error.err_add(self.errors, self.pos,
                              'SYNTAX_ERROR', 'expected separator, got: "' +
                              self.buf[:6] + '..."')
                raise error.Abort
            

            if m.group(2) == None: # no prefix
                return m.group(3)
            else:
                return (m.group(2), m.group(3))
Esempio n. 4
0
 def validate(self, errors, pos, val, errstr=''):
     if val < self.min or val > self.max:
         err_add(errors, pos, 'TYPE_VALUE',
                 (str(val), self.definition, 'range error' + errstr))
         return False
     else:
         return True
 def validate(self, errors, pos, val, errstr = ''):
     if val < self.min or val > self.max:
         err_add(errors, pos, 'TYPE_VALUE',
                 (str(val), self.definition, 'range error' + errstr))
         return False
     else:
         return True
Esempio n. 6
0
 def validate(self, errors, pos, val, errstr=''):
     if util.keysearch(val, 0, self.enums) == None:
         err_add(errors, pos, 'TYPE_VALUE',
                 (val, self.definition, 'enum not defined' + errstr))
         return False
     else:
         return True
Esempio n. 7
0
 def validate(self, errors, pos, val, errstr=''):
     for v in val:
         if util.keysearch(v, 0, self.bits) == None:
             err_add(errors, pos, 'TYPE_VALUE',
                     (v, self.definition, 'bit not defined' + errstr))
             return False
     return True
Esempio n. 8
0
    def get_keyword(self):
        """ret: identifier | (prefix, identifier)"""
        self.skip()

        m = syntax.re_keyword.match(self.buf)
        if m == None:
            error.err_add(self.errors, self.pos, 'SYNTAX_ERROR',
                          'illegal keyword: ' + self.buf)
            raise error.Abort
        else:
            self.set_buf(m.end())
            # check the separator
            if (self.buf[0].isspace()
                    or (self.buf[0] == '/' and self.buf[1] in ('/', '*'))
                    or (self.buf[0] in (';', '{'))):
                pass
            else:
                error.err_add(
                    self.errors, self.pos, 'SYNTAX_ERROR',
                    'expected separator, got: "' + self.buf[:6] + '..."')
                raise error.Abort

            if m.group(2) == None:  # no prefix
                return m.group(3)
            else:
                return (m.group(2), m.group(3))
Esempio n. 9
0
    def parse(self, ctx, ref, text):
        """Parse the string `text` containing a YIN (sub)module.

        Return a Statement on success or None on failure.
        """

        self.ctx = ctx
        self.pos = error.Position(ref)
        self.top = None

        self.uri = None
        self.nsmap = {}
        self.prefixmap = {}
        self.included = []
        self.extensions = {}

        self.data = ''
        self.element_stack = []

        try:
            self.parser.Parse(text, True)
        except error.Abort:
            return None
        except expat.ExpatError, ex:
            self.pos.line = ex.lineno
            error.err_add(self.ctx.errors, self.pos, 'SYNTAX_ERROR',
                          str(ex).split(":")[0])
            return None
Esempio n. 10
0
def validate_range_expr(errors, stmt, type_):
    # break the expression apart
    def f(lostr, histr):
        if histr == '':
            # this means that a single number was in the range, e.g.
            # "4 | 5..6".
            return (type_.i_type_spec.str_to_val(errors, stmt.pos,
                                                 lostr), None)
        return (type_.i_type_spec.str_to_val(errors, stmt.pos, lostr),
                type_.i_type_spec.str_to_val(errors, stmt.pos, histr))

    ranges = [f(m[1], m[6]) for m in syntax.re_range_part.findall(stmt.arg)]
    # make sure the range values are of correct type and increasing
    pos = stmt.pos
    cur_lo = None
    for (lo, hi) in ranges:
        if lo != 'min' and lo != 'max':
            type_.i_type_spec.validate(errors, pos, lo)
        if hi != 'min' and hi != 'max' and hi != None:
            type_.i_type_spec.validate(errors, pos, hi)
        # check that cur_lo < lo < hi
        if not is_smaller(cur_lo, lo):
            err_add(errors, pos, 'RANGE_BOUNDS', (str(lo), cur_lo))
            return None
        if not is_smaller(lo, hi):
            err_add(errors, pos, 'RANGE_BOUNDS', (str(hi), str(lo)))
            return None
        if hi == None:
            cur_lo = lo
        else:
            cur_lo = hi
    return (ranges, stmt.pos)
Esempio n. 11
0
 def str_to_val(self, errors, pos, str):
     if str == 'true': return True
     elif str == 'false': return False
     else:
         err_add(errors, pos, 'TYPE_VALUE',
                 (str, self.definition, 'not a boolean'))
         return None
    def _parse_statement(self, parent):
        keywd = self.tokenizer.get_keyword()
        # check for argument
        tok = self.tokenizer.peek()
        if tok == '{' or tok == ';':
            arg = None
        else:
            arg = self.tokenizer.get_string()

        stmt = statements.Statement(self.top, parent, self.pos, keywd, arg)
        if self.top is None:
            self.pos.top = stmt
            self.top = stmt
 
        # check for substatements
        tok = self.tokenizer.peek()
        if tok == '{':
            self.tokenizer.skip_tok() # skip the '{'
            while self.tokenizer.peek() != '}':
                substmt = self._parse_statement(stmt)
                stmt.substmts.append(substmt)
            self.tokenizer.skip_tok() # skip the '}'
        elif tok == ';':
            self.tokenizer.skip_tok() # skip the ';'
        else:
            error.err_add(self.ctx.errors, self.pos, 'INCOMPLETE_STATEMENT',
                          (keywd, tok))
            raise error.Abort
        return stmt
Esempio n. 13
0
 def start_element(self, name, attrs):
     name = str(name) # convert from unicode strings
     self.pos.line = self.lineno
     (ns, local_name) = self.split_qname(name)
     e = Element(ns, local_name, attrs, self.pos)
     if self.data.lstrip() != '':
         error.err_add(self.ctx.errors, self.pos, 'SYNTAX_ERROR',
                       "unexpected element - mixed content")
     self.data = ''
     if self.element_stack == []:
         # this is the top-level element
         self.top = e
         self.element_stack.append(e)
         # special case - the top-level statement has its argument
         # as an attribute, so we can save it here
         try:
             (argname, _arg_is_elem) = syntax.yin_map[e.local_name]
             arg = e.find_attribute(argname)
             self.pos.top_name = arg
         except:
             pass
         return
     else:
         parent = self.element_stack[-1]
         parent.children.append(e)
         self.element_stack.append(e)
Esempio n. 14
0
    def _parse_statement(self, parent):
        keywd = self.tokenizer.get_keyword()
        # check for argument
        tok = self.tokenizer.peek()
        if tok == '{' or tok == ';':
            arg = None
        else:
            arg = self.tokenizer.get_string()

        stmt = statements.Statement(self.top, parent, self.pos, keywd, arg)
        if self.top is None:
            self.pos.top_name = arg
            self.top = stmt

        # check for substatements
        tok = self.tokenizer.peek()
        if tok == '{':
            self.tokenizer.skip_tok()  # skip the '{'
            while self.tokenizer.peek() != '}':
                substmt = self._parse_statement(stmt)
                stmt.substmts.append(substmt)
            self.tokenizer.skip_tok()  # skip the '}'
        elif tok == ';':
            self.tokenizer.skip_tok()  # skip the ';'
        else:
            error.err_add(self.ctx.errors, self.pos, 'INCOMPLETE_STATEMENT',
                          (keywd, tok))
            raise error.Abort
        return stmt
 def str_to_val(self, errors, pos, str):
     if str == 'true': return True;
     elif str == 'false': return False
     else:
         err_add(errors, pos, 'TYPE_VALUE',
                 (str, self.definition, 'not a boolean'))
         return None
def validate_range_expr(errors, stmt, type_):
    # break the expression apart
    def f(lostr, histr):
        if histr == '':
            # this means that a single number was in the range, e.g.
            # "4 | 5..6".
            return (type_.i_type_spec.str_to_val(errors, stmt.pos, lostr),
                    None)
        return (type_.i_type_spec.str_to_val(errors, stmt.pos, lostr),
                type_.i_type_spec.str_to_val(errors, stmt.pos, histr))
    ranges = [f(m[1], m[6]) for m in syntax.re_range_part.findall(stmt.arg)]
    # make sure the range values are of correct type and increasing
    pos = stmt.pos
    cur_lo = None
    for (lo, hi) in ranges:
        if lo != 'min' and lo != 'max':
            type_.i_type_spec.validate(errors, pos, lo)
        if hi != 'min' and hi != 'max' and hi != None:
            type_.i_type_spec.validate(errors, pos, hi)
        # check that cur_lo < lo < hi
        if not is_smaller(cur_lo, lo):
            err_add(errors, pos, 'RANGE_BOUNDS', (str(lo), cur_lo))
            return None
        if not is_smaller(lo, hi):
            err_add(errors, pos, 'RANGE_BOUNDS', (str(hi), str(lo)))
            return None
        if hi == None:
            cur_lo = lo
        else:
            cur_lo = hi
    return (ranges, stmt.pos)
Esempio n. 17
0
    def create_statement(self, e, parent):
        if e.ns == yin_namespace:
            keywd = e.local_name
            try:
                (argname, arg_is_elem) = syntax.yin_map[keywd]
            except KeyError:
                error.err_add(self.ctx.errors, e.pos,
                              'UNKNOWN_KEYWORD', keywd)
                return None
        else:
            # extension
            try:
                prefix = self.prefixmap[e.ns]
            except KeyError:
                error.err_add(self.ctx.errors, e.pos,
                              'MODULE_NOT_IMPORTED', e.ns)
                return None
            keywd = (prefix, e.local_name)
            keywdstr = util.keyword_to_str(keywd)
            res = self.find_extension(e.ns, e.local_name)
            if res is None:
                error.err_add(self.ctx.errors, e.pos,
                              'UNKNOWN_KEYWORD', keywdstr)
                return None
            (arg_is_elem, argname)  = res

        keywdstr = util.keyword_to_str(keywd)
        if arg_is_elem == True:
            # find the argument element
            arg_elem = e.find_child(e.ns, argname)
            if arg_elem is None:
                arg = None
                error.err_add(self.ctx.errors, e.pos,
                              'MISSING_ARGUMENT_ELEMENT', (argname, keywdstr))

            else:
                arg = arg_elem.data
                e.remove_child(arg_elem)
        elif arg_is_elem == False:
            arg = e.find_attribute(argname)
            if arg is None:
                error.err_add(self.ctx.errors, e.pos,
                              'MISSING_ARGUMENT_ATTRIBUTE', (argname, keywdstr))
            else:
                e.remove_attribute(argname)
        else:
            # no arguments
            arg = None

        self.check_attr(e.pos, e.attrs)
            
        stmt = statements.Statement(self.top, parent, e.pos, keywd, arg)
        if self.top is None:
            self.top = stmt
        else:
            parent.substmts.append(stmt)

        for ch in e.children:
            self.create_statement(ch, stmt)
Esempio n. 18
0
 def str_to_val(self, errors, pos, str):
     dbg('trying to convert "%s" to a boolean...' % str)
     if str == 'true': return True
     elif str == 'false': return False
     else:
         err_add(errors, pos, 'TYPE_VALUE',
                 (str, self.definition, 'not a boolean'))
         return None
Esempio n. 19
0
 def str_to_val(self, errors, pos, str):
     dbg('trying to convert "%s" to a boolean...' % str)
     if str == 'true': return True;
     elif str == 'false': return False
     else:
         err_add(errors, pos, 'TYPE_VALUE',
                 (str, self.definition, 'not a boolean'))
         return None
Esempio n. 20
0
 def str_to_val(self, errors, pos, str):
     try:
         if str in ['min', 'max']:
             return str
         return int(str, 0)
     except ValueError:
         err_add(errors, pos, 'TYPE_VALUE',
                 (str, self.definition, 'not an integer'))
         return None
 def str_to_val(self, errors, pos, str):
     try:
         if str in ['min', 'max']:
             return str
         return int(str, 0)
     except ValueError:
         err_add(errors, pos, 'TYPE_VALUE',
                 (str, self.definition, 'not an integer'))
         return None
Esempio n. 22
0
 def str_to_val(self, errors, pos, str):
     try:
         dbg('trying to convert "%s" to an int...' % str)
         if str in ['min', 'max']:
             return str
         return int(str, 0)
     except ValueError:
         err_add(errors, pos, 'TYPE_VALUE',
                 (str, self.definition, 'not an integer'))
         return None
Esempio n. 23
0
 def str_to_val(self, errors, pos, str):
     try:
         dbg('trying to convert "%s" to an int...' % str)
         if str in ['min', 'max']:
             return str
         return int(str, 0)
     except ValueError:
         err_add(errors, pos, 'TYPE_VALUE',
                 (str, self.definition, 'not an integer'))
         return None
 def validate(self, errors, pos, val, errstr=''):
     if self.base.validate(errors, pos, val, errstr) == False:
         return False
     for (re, re_pos) in self.res:
         if re.regexpExec(val) != 1:
             err_add(errors, pos, 'TYPE_VALUE',
                     (val, self.definition, 'pattern mismatch' + errstr +
                      ' for pattern defined at ' + str(re_pos)))
             return False
     return True
Esempio n. 25
0
 def validate(self, errors, pos, val, errstr=''):
     if self.base.validate(errors, pos, val, errstr) == False:
         return False
     for (re, re_pos) in self.res:
         if re.regexpExec(val) != 1:
             err_add(errors, pos, 'TYPE_VALUE',
                     (val, self.definition, 'pattern mismatch' + errstr +
                      ' for pattern defined at ' + str(re_pos)))
             return False
     return True
 def readline(self):
     if len(self.lines) == 0:
         raise error.Eof
     self.buf = self.lines[0]
     del self.lines[0]
     self.pos.line += 1
     self.offset = 0
     if (self.max_line_len is not None and
         len(self.buf) > self.max_line_len):
         error.err_add(self.errors, self.pos, 'LONG_LINE',
                       (len(self.buf), self.max_line_len))
Esempio n. 27
0
 def validate(self, errors, pos, val, errstr=''):
     if self.base.validate(errors, pos, val, errstr) == False:
         return False
     for (lo, hi) in self.ranges:
         if ((lo == 'min' or val >= lo) and
             ((hi == None and val == lo) or hi == 'max' or val <= hi)):
             return True
     err_add(errors, pos, 'TYPE_VALUE',
             (str(val), self.definition, 'range error' + errstr +
              ' for range defined at ' + str(self.ranges_pos)))
     return False
Esempio n. 28
0
 def readline(self):
     if len(self.lines) == 0:
         raise error.Eof
     self.buf = self.lines[0]
     del self.lines[0]
     self.pos.line += 1
     self.offset = 0
     if (self.max_line_len is not None
             and len(self.buf) > self.max_line_len):
         error.err_add(self.errors, self.pos, 'LONG_LINE',
                       (len(self.buf), self.max_line_len))
Esempio n. 29
0
    def check_attr(self, pos, attrs):
        """Check for unknown attributes."""

        for at in attrs:
            (ns, local_name) = self.split_qname(at)
            if ns is None:
                error.err_add(self.ctx.errors, pos,
                              'UNEXPECTED_ATTRIBUTE', local_name)
            elif ns == yin_namespace:
                error.err_add(self.ctx.errors, pos,
                              'UNEXPECTED_ATTRIBUTE', "{"+at)
 def validate(self, errors, pos, str, errstr = ''):
     # try to validate against each membertype
     for t in self.types:
         if t.i_type_spec != None:
             val = t.i_type_spec.str_to_val([], pos, str)
             if val != None:
                 if t.i_type_spec.validate([], pos, val):
                     return True;
     err_add(errors, pos, 'TYPE_VALUE',
             (str, self.definition, 'no member type matched' + errstr))
     return False
Esempio n. 31
0
 def validate(self, errors, pos, str, errstr=''):
     # try to validate against each membertype
     for t in self.types:
         if t.i_type_spec != None:
             val = t.i_type_spec.str_to_val([], pos, str)
             if val != None:
                 if t.i_type_spec.validate([], pos, val):
                     return True
     err_add(errors, pos, 'TYPE_VALUE',
             (str, self.definition, 'no member type matched' + errstr))
     return False
 def validate(self, errors, pos, val, errstr=''):
         if self.base.validate(errors, pos, val, errstr) == False:
             return False
         for (lo, hi) in self.ranges:
             if ((lo == 'min' or val >= lo) and
                 ((hi == None and val == lo) or hi == 'max' or val <= hi)):
                 return True
         err_add(errors, pos, 'TYPE_VALUE',
                 (str(val), self.definition, 'range error' + errstr +
                  ' for range defined at ' + str(self.ranges_pos)))
         return False
 def validate(self, errors, pos, val, errstr=''):
     if self.base.validate(errors, pos, val, errstr) == False:
         return False
     vallen = len(val)
     for (lo, hi) in self.lengths:
         if ((lo == 'min' or vallen >= lo) and
             ((hi == None and vallen == lo) or hi == 'max' or vallen <= hi)):
             return True
     err_add(errors, pos, 'TYPE_VALUE',
             (val, self.definition, 'length error' + errstr + 
              ' for length defined at ' + str(self.length_pos)))
     return False
Esempio n. 34
0
 def validate(self, errors, pos, val, errstr=''):
     if self.base.validate(errors, pos, val, errstr) == False:
         return False
     vallen = len(val)
     for (lo, hi) in self.lengths:
         if ((lo == 'min' or vallen >= lo)
                 and ((hi == None and vallen == lo) or hi == 'max'
                      or vallen <= hi)):
             return True
     err_add(errors, pos, 'TYPE_VALUE',
             (val, self.definition, 'length error' + errstr +
              ' for length defined at ' + str(self.length_pos)))
     return False
Esempio n. 35
0
    def search_module(self, pos, modulename, revision=None):
        """Searches for a module named `modulename` in the repository

        If the module is found, it is added to the context.
        Returns the module if found, and None otherwise"""

        if modulename not in self.revs:
            # this module doesn't exist in the repos at all
            error.err_add(self.errors, pos, 'MODULE_NOT_FOUND', modulename)
            # keep track of this to avoid multiple errors
            self.revs[modulename] = []
            return None
        elif self.revs[modulename] == []:
            # this module doesn't exist in the repos at all, error reported
            return None

        if revision is not None:
            if (modulename, revision) in self.modules:
                return self.modules[(modulename, revision)]
            self._ensure_revs(self.revs[modulename])
            x = util.keysearch(revision, 0, self.revs[modulename])
            if x is not None:
                (_revision, handle) = x
                if handle == None:
                    # this revision doesn't exist in the repos, error reported
                    return None
            else:
                # this revision doesn't exist in the repos
                error.err_add(self.errors, pos, 'MODULE_NOT_FOUND_REV',
                              (modulename, revision))
                # keep track of this to avoid multiple errors
                self.revs[modulename].append((revision, None))
                return None
        else:
            # get the latest revision
            (revision, handle) = self._get_latest_rev(self.revs[modulename])
            if (modulename, revision) in self.modules:
                return self.modules[(modulename, revision)]

        if handle is None:
            module = None
        elif handle[0] == 'parsed':
            module = handle[1]
            ref = handle[2]
            if modulename != module.arg:
                error.err_add(self.errors, module.pos, 'BAD_MODULE_NAME',
                              (module.arg, ref, modulename))
                module = None
            else:
                module = self.add_parsed_module(handle[1])
        else:
            # get it from the repos
            try:
                r = self.repository.get_module_from_handle(handle)
                (ref, format, text) = r
                module = self.add_module(ref, text, format, modulename,
                                         revision)
            except self.repository.ReadError, ex:
                error.err_add(self.errors, pos, 'READ_ERROR', str(ex))
                module = None
    def search_module(self, pos, modulename, revision=None):
        """Searches for a module named `modulename` in the repository

        If the module is found, it is added to the context.
        Returns the module if found, and None otherwise"""

        if modulename not in self.revs:
            # this module doesn't exist in the repos at all
            error.err_add(self.errors, pos, 'MODULE_NOT_FOUND', modulename)
            # keep track of this to avoid multiple errors
            self.revs[modulename] = []
            return None
        elif self.revs[modulename] == []:
            # this module doesn't exist in the repos at all, error reported
            return None

        if revision is not None:
            if (modulename,revision) in self.modules:
                return self.modules[(modulename, revision)]
            self._ensure_revs(self.revs[modulename])
            x = util.keysearch(revision, 0, self.revs[modulename])
            if x is not None:
                (_revision, handle) = x
                if handle == None:
                    # this revision doesn't exist in the repos, error reported
                    return None
            else:
                # this revision doesn't exist in the repos
                error.err_add(self.errors, pos, 'MODULE_NOT_FOUND_REV',
                              (modulename, revision))
                # keep track of this to avoid multiple errors
                self.revs[modulename].append((revision, None))
                return None
        else:
            # get the latest revision
            (revision, handle) = self._get_latest_rev(self.revs[modulename])
            if (modulename, revision) in self.modules:
                return self.modules[(modulename, revision)]
            
        if handle is None:
            module = None
        elif handle[0] == 'parsed':
            module = handle[1]
            ref = handle[2]
            if modulename != module.arg:
                error.err_add(self.errors, module.pos, 'BAD_MODULE_NAME',
                              (module.arg, ref, modulename))
                module = None
            else:
                module = self.add_parsed_module(handle[1])
        else:
            # get it from the repos
            try:
                r = self.repository.get_module_from_handle(handle)
                (ref, format, text) = r
                module = self.add_module(ref, text, format, modulename, revision)
            except self.repository.ReadError, ex:
                error.err_add(self.errors, pos, 'READ_ERROR', str(ex))
                module = None
Esempio n. 37
0
 def validate(self):
     uris = {}
     for k in self.modules:
         m = self.modules[k]
         if m != None:
             namespace = m.search_one('namespace')
             if namespace != None:
                 uri = namespace.arg
                 if uri in uris:
                     if uris[uri] != m.arg:
                         error.err_add(self.errors, namespace.pos,
                                       'DUPLICATE_NAMESPACE',
                                       (uri, uris[uri]))
                 else:
                     uris[uri] = m.arg
Esempio n. 38
0
 def validate(self):
     uris = {}
     for k in self.modules:
         m = self.modules[k]
         if m != None:
             namespace = m.search_one('namespace')
             if namespace != None:
                 uri = namespace.arg
                 if uri in uris:
                     if uris[uri] != m.arg:
                         error.err_add(self.errors, namespace.pos,
                                       'DUPLICATE_NAMESPACE',
                                       (uri, uris[uri]))
                 else:
                     uris[uri] = m.arg
Esempio n. 39
0
def validate_pattern_expr(errors, stmt):
    # check that it's syntactically correct
    try:
        import libxml2
        try:
            re = libxml2.regexpCompile(stmt.arg)
            return (re, stmt.pos)
        except libxml2.treeError, v:
            err_add(errors, stmt.pos, 'PATTERN_ERROR', str(v))
            return None
    except ImportError:
        err_add(errors, stmt.pos, 'PATTERN_FAILURE',
                "Could not import python module libxml2 "
                    "(see http://xmlsoft.org for installation help)")
        return None
Esempio n. 40
0
def validate_pattern_expr(errors, stmt):
    # check that it's syntactically correct
    try:
        import libxml2
        try:
            re = libxml2.regexpCompile(stmt.arg)
            return (re, stmt.pos)
        except libxml2.treeError, v:
            err_add(errors, stmt.pos, 'PATTERN_ERROR', str(v))
            return None
    except ImportError:
        err_add(
            errors, stmt.pos, 'PATTERN_FAILURE',
            "Could not import python module libxml2 "
            "(see http://xmlsoft.org for installation help)")
        return None
Esempio n. 41
0
class YangParser(object):
    def __init__(self, extra={}):
        pass

    def parse(self, ctx, ref, text):
        """Parse the string `text` containing a YANG statement.

        Return a Statement on success or None on failure
        """

        self.ctx = ctx
        self.pos = error.Position(ref)
        self.top = None

        try:
            self.tokenizer = YangTokenizer(text, self.pos, ctx.errors)
            stmt = self._parse_statement(None)
        except error.Abort:
            return None
        except error.Eof, e:
            error.err_add(self.ctx.errors, self.pos, 'EOF_ERROR', ())
            return None
        try:
            # we expect a error.Eof at this point, everything else is an error
            self.tokenizer.peek()
        except error.Eof:
            return stmt
        except:
            pass
        error.err_add(self.ctx.errors, self.pos, 'TRAILING_GARBAGE', ())
        return None
def validate_pattern_expr(errors, stmt):
    # check that it's syntactically correct
    try:
        import libxml2
        try:
            re = libxml2.regexpCompile(stmt.arg)
            return (re, stmt.pos)
        except libxml2.treeError, v:
            err_add(errors, stmt.pos, 'PATTERN_ERROR', str(v))
            return None
    except ImportError:
## Do not report a warning in this case.  Maybe we should add some
## flag to turn on this warning...
#        err_add(errors, stmt.pos, 'PATTERN_FAILURE',
#                "Could not import python module libxml2 "
#                    "(see http://xmlsoft.org for installation help)")
        return None
Esempio n. 43
0
def validate_pattern_expr(errors, stmt):
    # check that it's syntactically correct
    try:
        import libxml2
        try:
            re = libxml2.regexpCompile(stmt.arg)
            return (re, stmt.pos)
        except libxml2.treeError, v:
            err_add(errors, stmt.pos, 'PATTERN_ERROR', str(v))
            return None
    except ImportError:
        ## Do not report a warning in this case.  Maybe we should add some
        ## flag to turn on this warning...
        #        err_add(errors, stmt.pos, 'PATTERN_FAILURE',
        #                "Could not import python module libxml2 "
        #                    "(see http://xmlsoft.org for installation help)")
        return None
Esempio n. 44
0
    def parse(self, ctx, ref, text):
        """Parse the string `text` containing a YANG statement.

        Return a Statement on success or None on failure
        """

        self.ctx = ctx
        self.pos = error.Position(ref)
        self.top = None

        try:
            self.tokenizer = YangTokenizer(text, self.pos, ctx.errors)
            stmt = self._parse_statement(None)
        except error.Abort:
            return None
        except error.Eof, e:
            error.err_add(self.ctx.errors, self.pos, 'EOF_ERROR', ())
            return None
Esempio n. 45
0
    def parse(self, ctx, ref, text):
        """Parse the string `text` containing a YANG statement.

        Return a Statement on success or None on failure
        """

        self.ctx = ctx
        self.pos = error.Position(ref)
        self.top = None

        try:
            self.tokenizer = YangTokenizer(text, self.pos, ctx.errors)
            stmt = self._parse_statement(None)
        except error.Abort:
            return None
        except error.Eof, e:
            error.err_add(self.ctx.errors, self.pos, 'EOF_ERROR', ())
            return None
def validate_enums(errors, enums, stmt):
    if enums == []:
        err_add(errors, stmt.pos, 'MISSING_TYPE_SPEC',
                ('enumeration', 'enum'))
        return None
    # make sure all names and values given are unique
    names = {}
    values = {}
    next = 0
    for e in enums:
        e.i_value = None
        value = e.search_one('value')
        if value is not None:
            try:
                x = int(value.arg)
                e.i_value = x
                if x < -2147483648 or x > 2147483647:
                    raise ValueError
                if x >= next:
                    next = x + 1
                if x in values:
                    err_add(errors, value.pos, 'DUPLICATE_ENUM_VALUE', 
                            (x, values[x]))
                else:
                    values[x] = value.pos
                    
            except ValueError:
                err_add(errors, value.pos, 'ENUM_VALUE', value.arg)
        else:
            # auto-assign a value
            values[next] = e.pos
            if next > 2147483647:
                err_add(errors, e.pos, 'ENUM_VALUE', str(next))
            e.i_value = next
            next = next + 1
        if e.arg in names:
            err_add(errors, e.pos, 'DUPLICATE_ENUM_NAME', (e.arg, names[e.arg]))
        else:
            names[e.arg] = e.pos

    # check status (here??)
    return enums
Esempio n. 47
0
def validate_enums(errors, enums, stmt):
    if enums == []:
        err_add(errors, stmt.pos, 'MISSING_TYPE_SPEC', ('enumeration', 'enum'))
        return None
    # make sure all names and values given are unique
    names = {}
    values = {}
    next = 0
    for e in enums:
        e.i_value = None
        value = e.search_one('value')
        if value is not None:
            try:
                x = int(value.arg)
                e.i_value = x
                if x < -2147483648 or x > 2147483647:
                    raise ValueError
                if x >= next:
                    next = x + 1
                if x in values:
                    err_add(errors, value.pos, 'DUPLICATE_ENUM_VALUE',
                            (x, values[x]))
                else:
                    values[x] = value.pos

            except ValueError:
                err_add(errors, value.pos, 'ENUM_VALUE', value.arg)
        else:
            # auto-assign a value
            values[next] = e.pos
            if next > 2147483647:
                err_add(errors, e.pos, 'ENUM_VALUE', str(next))
            e.i_value = next
            next = next + 1
        if e.arg in names:
            err_add(errors, e.pos, 'DUPLICATE_ENUM_NAME',
                    (e.arg, names[e.arg]))
        else:
            names[e.arg] = e.pos

    # check status (here??)
    return enums
Esempio n. 48
0
 def str_to_val(self, errors, pos, s0):
     if s0 in ('min', 'max'):
         return s0
     # make sure it is syntactically correct
     if syntax.re_decimal.search(s0) is None:
         err_add(errors, pos, 'TYPE_VALUE',
                 (s0, self.definition, 'not a decimal'))
         return None
     if s0[0] == '-':
         is_negative = True
         s = s0[1:]
     else:
         is_negative = False
         s = s0
     p = s.find('.')
     if p == -1:
         v = int(s)
         i = self.fraction_digits
         while i > 0:
             v = v * 10
             i -= 1
     else:
         v = int(s[:p])
         i = self.fraction_digits
         j = p + 1
         #            slen = len(s.rstrip('0')) # ignore trailing zeroes
         # No, do not ignore trailing zeroes!
         slen = len(s)
         while i > 0:
             v *= 10
             i -= 1
             if j < slen:
                 v += int(s[j])
             j += 1
         if j < slen:
             err_add(errors, pos, 'TYPE_VALUE',
                     (s, self.definition, 'too many fraction digits'))
             return None
     if is_negative:
         v = -v
     return Decimal64Value(v, s0)
    def str_to_val(self, errors, pos, s0):
        if s0 in ('min', 'max'):
            return s0
        # make sure it is syntactically correct
        if syntax.re_decimal.search(s0) is None:
            err_add(errors, pos, 'TYPE_VALUE',
                    (s0, self.definition, 'not a decimal'))
            return None
        if s0[0] == '-':
            is_negative = True
            s = s0[1:]
        else:
            is_negative = False
            s = s0
        p = s.find('.')
        if p == -1:
            v = int(s)
            i = self.fraction_digits
            while i > 0:
                v = v * 10
                i -= 1
        else:
            v = int(s[:p])
            i = self.fraction_digits
            j = p + 1
#            slen = len(s.rstrip('0')) # ignore trailing zeroes
# No, do not ignore trailing zeroes!
            slen = len(s)
            while i > 0:
                v *= 10
                i -= 1
                if j < slen:
                    v += int(s[j])
                j += 1
            if j < slen:
                err_add(errors, pos, 'TYPE_VALUE',
                        (s, self.definition, 'too many fraction digits'))
                return None
        if is_negative:
            v = -v
        return Decimal64Value(v, s0)
Esempio n. 50
0
    def add_parsed_module(self, module):
        if module is None:
            return None
        if module.arg is None:
            error.err_add(self.errors, module.pos,
                          'EXPECTED_ARGUMENT', module.keyword)
            return None
        top_keywords = ['module', 'submodule']
        if module.keyword not in top_keywords:
            error.err_add(self.errors, module.pos,
                          'UNEXPECTED_KEYWORD_N', (module.keyword, top_keywords))
            return None

        rev = util.get_latest_revision(module)
        if (module.arg, rev) in self.modules:
            other = self.modules[(module.arg, rev)]
            if (hasattr(other, 'i_adler32') and
                hasattr(module, 'i_adler32') and
                other.i_adler32 != module.i_adler32):
                error.err_add(self.errors, module.pos,
                              'DUPLICATE_MODULE', (module.arg, other.pos))
                return None
            # exactly same module
            return other

        self.modules[(module.arg, rev)] = module
        statements.validate_module(self, module)

        return module
Esempio n. 51
0
    def add_parsed_module(self, module):
        if module is None:
            return None
        if module.arg is None:
            error.err_add(self.errors, module.pos, 'EXPECTED_ARGUMENT',
                          module.keyword)
            return None
        top_keywords = ['module', 'submodule']
        if module.keyword not in top_keywords:
            error.err_add(self.errors, module.pos, 'UNEXPECTED_KEYWORD_N',
                          (module.keyword, top_keywords))
            return None

        rev = util.get_latest_revision(module)
        if (module.arg, rev) in self.modules:
            other = self.modules[(module.arg, rev)]
            if (hasattr(other, 'i_adler32') and hasattr(module, 'i_adler32')
                    and other.i_adler32 != module.i_adler32):
                error.err_add(self.errors, module.pos, 'DUPLICATE_MODULE',
                              (module.arg, other.pos))
                return None
            # exactly same module
            return other

        self.modules[(module.arg, rev)] = module
        statements.validate_module(self, module)

        return module
 def str_to_val(self, errors, pos, s):
     if s.find(":") == -1:
         prefix = None
         name = s
     else:
         [prefix, name] = s.split(':', 1)
     if prefix is None or self.base.i_module.i_prefix == prefix:
         # check local identities
         pmodule = self.base.i_module
     else:
         # this is a prefixed name, check the imported modules
         pmodule = statements.prefix_to_module(self.base.i_module, prefix,
                                               pos, errors)
         if pmodule is None:
             return None
     if name not in pmodule.i_identities:
         err_add(errors, pos, 'TYPE_VALUE',
                 (s, self.definition, 'identityref not found'))
         return None
     val = pmodule.i_identities[name]
     my_identity = self.base.i_identity
     vals = []
     while True:
         if val == my_identity:
             return pmodule.i_identities[name]
         else:
             p = val.search_one('base')
             if p is None or p.i_identity is None:
                 err_add(errors, pos, 'TYPE_VALUE',
                         (s, self.definition,
                          'identityref not derived from %s' % \
                          my_identity.arg))
                 return None
             else:
                 val = p.i_identity
                 if val in vals:
                     # circular; has been reported already
                     return
                 vals.append(val)
Esempio n. 53
0
 def str_to_val(self, errors, pos, s):
     if s.find(":") == -1:
         prefix = None
         name = s
     else:
         [prefix, name] = s.split(':', 1)
     if prefix is None or self.base.i_module.i_prefix == prefix:
         # check local identities
         pmodule = self.base.i_module
     else:
         # this is a prefixed name, check the imported modules
         pmodule = statements.prefix_to_module(self.base.i_module, prefix,
                                               pos, errors)
         if pmodule is None:
             return None
     if name not in pmodule.i_identities:
         err_add(errors, pos, 'TYPE_VALUE',
                 (s, self.definition, 'identityref not found'))
         return None
     val = pmodule.i_identities[name]
     my_identity = self.base.i_identity
     vals = []
     while True:
         if val == my_identity:
             return pmodule.i_identities[name]
         else:
             p = val.search_one('base')
             if p is None or p.i_identity is None:
                 err_add(errors, pos, 'TYPE_VALUE',
                         (s, self.definition,
                          'identityref not derived from %s' % \
                          my_identity.arg))
                 return None
             else:
                 val = p.i_identity
                 if val in vals:
                     # circular; has been reported already
                     return
                 vals.append(val)
Esempio n. 54
0
    def add_module(self,
                   ref,
                   text,
                   format=None,
                   expect_modulename=None,
                   expect_revision=None,
                   expect_failure_error=True):
        """Parse a module text and add the module data to the context

        `ref` is a string which is used to identify the source of
              the text for the user.  used in error messages
        `text` is the raw text data
        `format` is one of 'yang' or 'yin'.

        Returns the parsed and validated module on success, and None on error.
        """
        if format == None:
            format = util.guess_format(text)

        if format == 'yin':
            p = yin_parser.YinParser()
        else:
            p = yang_parser.YangParser()

        module = p.parse(self, ref, text)
        if module is None:
            return None

        if expect_modulename is not None and expect_modulename != module.arg:
            if expect_failure_error:
                error.err_add(self.errors, module.pos, 'BAD_MODULE_NAME',
                              (module.arg, ref, expect_modulename))
                return None
            else:
                error.err_add(self.errors, module.pos, 'WBAD_MODULE_NAME',
                              (module.arg, ref, expect_modulename))
        if expect_revision is not None:
            latest_rev = util.get_latest_revision(module)
            if expect_revision != latest_rev:
                if expect_failure_error:
                    error.err_add(self.errors, module.pos, 'BAD_REVISION',
                                  (latest_rev, ref, expect_revision))
                    return None
                else:
                    error.err_add(self.errors, module.pos, 'WBAD_REVISION',
                                  (latest_rev, ref, expect_revision))

        module.i_adler32 = zlib.adler32(text)
        return self.add_parsed_module(module)
 def f(lostr, histr):
     try:
         if lostr in ['min', 'max']:
             lo = lostr
         else:
             lo = int(lostr)
     except ValueError:
         err_add(errors, stmt.pos, 'TYPE_VALUE',
                 (lostr, '', 'not an integer'))
         return (None, None)
     try:
         if histr == '':
             # this means that a single number was in the length, e.g.
             # "4 | 5..6".
             return (lo, None)
         if histr in ['min', 'max']:
             hi = histr
         else:
             hi = int(histr)
     except ValueError:
         err_add(errors, stmt.pos, 'TYPE_VALUE',
                 (histr, '', 'not an integer'))
         return None
     return (lo, hi)
    def add_module(self, ref, text, format=None,
                   expect_modulename=None, expect_revision=None,
                   expect_failure_error=True):
        """Parse a module text and add the module data to the context

        `ref` is a string which is used to identify the source of
              the text for the user.  used in error messages
        `text` is the raw text data
        `format` is one of 'yang' or 'yin'.

        Returns the parsed and validated module on success, and None on error.
        """
        if format == None:
            format = util.guess_format(text)

        if format == 'yin':
            p = yin_parser.YinParser()
        else:
            p = yang_parser.YangParser()

        module = p.parse(self, ref, text)
        if module is None:
            return None

        if expect_modulename is not None and expect_modulename != module.arg:
            if expect_failure_error:
                error.err_add(self.errors, module.pos, 'BAD_MODULE_NAME',
                              (module.arg, ref, expect_modulename))
                return None
            else:
                error.err_add(self.errors, module.pos, 'WBAD_MODULE_NAME',
                              (module.arg, ref, expect_modulename))
        if expect_revision is not None:
            latest_rev = util.get_latest_revision(module)
            if expect_revision != latest_rev:
                if expect_failure_error:
                    error.err_add(self.errors, module.pos, 'BAD_REVISION',
                                  (latest_rev, ref, expect_revision))
                    return None
                else:
                    error.err_add(self.errors, module.pos, 'WBAD_REVISION',
                                  (latest_rev, ref, expect_revision))

        module.i_adler32 = zlib.adler32(text)
        return self.add_parsed_module(module)