def _ensure_revs(self, revs): i = 0 length = len(revs) while i < length: (rev, handle) = revs[i] if rev is None: # now we must read the revision from the module try: r = self.repository.get_module_from_handle(handle) except self.repository.ReadError, ex: i += 1 continue (ref, format, text) = r if format == None: format = util.guess_format(text) if format == 'yin': p = yin_parser.YinParser({ 'no_include': True, 'no_extensions': True }) else: p = yang_parser.YangParser() module = p.parse(self, ref, text) if module is not None: rev = util.get_latest_revision(module) revs[i] = (rev, ('parsed', module, ref)) i += 1
def read_module(self, modulename, revision=None, extra={}): """Searches for a module named `modulename` in the repository The module is just read, and not compiled at all. Returns the module if found, and None otherwise""" if modulename not in self.revs: # this module doesn't exist in the repos at all 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, 1, 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 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[0] == 'parsed': module = handle[1] return module else: # get it from the repos try: r = self.repository.get_module_from_handle(handle) (ref, format, text) = r if format == None: format = util.guess_format(text) if format == 'yin': p = yin_parser.YinParser(extra) else: p = yang_parser.YangParser(extra) return p.parse(self, ref, text) except self.repository.ReadError, ex: return None
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 add_module(self, ref, text, format=None): """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 module.i_adler32 = zlib.adler32(text) return self.add_parsed_module(module)
class FileRepository(Repository): def __init__(self, path=""): """Create a Repository which searches the filesystem for modules `path` is a `os.pathsep`-separated string of directories """ Repository.__init__(self) self.dirs = string.split(path, os.pathsep) # add standard search path self.dirs.append('.') modpath = os.getenv('YANG_MODPATH') if modpath is not None: self.dirs.extend(string.split(modpath, os.pathsep)) home = os.getenv('HOME') if home is not None: self.dirs.append(os.path.join(home, 'yang', 'modules')) inst = os.getenv('YANG_INSTALL') if inst is not None: self.dirs.append(os.path.join(inst, 'yang', 'modules')) else: self.dirs.append( os.path.join(sys.prefix, 'share', 'yang', 'modules')) self.modules = None def _setup(self, ctx): # check all dirs for yang and yin files self.modules = [] r = re.compile(r"^(.*?)(\@(\d{4}-\d{2}-\d{2}))?\.(yang|yin)$") for d in self.dirs: try: files = os.listdir(d) except OSError: files = [] for fname in files: m = r.search(fname) if m is not None: (name, _dummy, rev, format) = m.groups() absfilename = os.path.join(d, fname) if absfilename.startswith("./"): absfilename = absfilename[2:] handle = (format, absfilename) self.modules.append((name, rev, handle)) # FIXME: bad strategy; when revisions are not used in the filename # this code parses all modules :( need to do this lazily def _peek_revision(self, absfilename, format, ctx): try: fd = file(absfilename) text = fd.read() except IOError, ex: return None if format == 'yin': p = yin_parser.YinParser() else: p = yang_parser.YangParser() # FIXME: optimization - do not parse the entire text # just to read the revisions... module = p.parse(ctx, absfilename, text) if module is None: return None return (util.get_latest_revision(module), module)