Exemple #1
0
    def parse_file(cls, fn):
        '''
        Parse a full EPICS dbd file and return a `DbdFile` instance.

        Parameters
        ----------
        fn : str or file
            dbd filename

        Returns
        ----------
        parsed : list
            pyPDB parsed dbd nodes
        '''
        import pyPDB.dbd.yacc as _yacc
        import pyPDB.dbdlint as _dbdlint

        if hasattr(fn, 'read'):
            contents = fn.read()
        else:
            with open(fn, 'rt') as f:
                contents = f.read()

        parsed = _yacc.parse(contents)
        results = cls()
        tree = copy.deepcopy(_dbdlint.dbdtree)

        # Walk the dbd file, populating the results dictionaries:
        _dbdlint.walk(parsed, tree, results)
        return results
Exemple #2
0
    def __init__(self, fn):
        if hasattr(fn, 'read'):
            self.filename = getattr(fn, 'name', None)
            contents = fn.read()
        else:
            self.filename = str(fn)
            with open(fn, 'rt') as f:
                contents = f.read()

        self.parsed = _yacc.parse(contents)
Exemple #3
0
def lint_db(
    dbd,
    db,
    *,
    full=True,
    warn_ext_links=False,
    warn_bad_fields=True,
    warn_rec_append=False,
    warn_quoted=False,
    warn_varint=True,
    warn_spec_comm=True,
):
    '''
    Lint a db (database) file using its database definition file (dbd) using
    pyPDB.

    Parameters
    ----------
    dbd : DbdFile or str
        The database definition file; filename or pre-loaded DbdFile
    db : str
        The database filename or text
    full : bool, optional
        Validate as a complete database
    warn_quoted : bool, optional
        A node argument isn't quoted
    warn_varint : bool, optional
        A variable(varname) node which doesn't specify a type, which defaults
        to 'int'
    warn_spec_comm : bool, optional
        Syntax error in special #: comment line
    warn_ext_link : bool, optional
        A DB/CA link to a PV which is not defined.  Add '#: external("pv.FLD")
    warn_bad_field : bool, optional
        Unable to validate record instance field due to a previous error
        (missing recordtype).
    warn_rec_append : bool, optional
        Not using Base >=3.15 style recordtype "*" when appending/overwriting
        record instances

    Raises
    ------
    DBSyntaxError
        When a syntax issue is discovered. Note that this exception contains
        file and line number information (attributes: fname, lineno, results)

    Returns
    -------
    results : LinterResults
    '''
    args = []
    if warn_ext_links:
        args.append('-Wext-link')
    if warn_bad_fields:
        args.append('-Wbad-field')
    if warn_rec_append:
        args.append('-Wrec-append')

    if not warn_quoted:
        args.append('-Wno-quoted')
    if not warn_varint:
        args.append('-Wno-varint')
    if not warn_spec_comm:
        args.append('-Wno-spec-comm')

    if full:
        args.append('-F')
    else:
        args.append('-P')

    dbd_file = (dbd if isinstance(dbd, DbdFile) else DbdFile(dbd))

    args = _dbdlint.getargs([dbd_file.filename, db, *args])

    results = LinterResults(args)

    if os.path.exists(db):
        with open(db, 'r') as f:
            db_content = f.read()
    else:
        db_content = db
        db = '<string>'

    try:
        _dbdlint.walk(dbd_file.parsed, _dbdlint.dbdtree, results)
        parsed_db = _yacc.parse(db_content, file=db)
        _dbdlint.walk(parsed_db, _dbdlint.dbdtree, results)
    except DBSyntaxError as ex:
        ex.errors = results.errors
        ex.warnings = results.warnings
        raise

    return results