Beispiel #1
0
def diff_files_internal(file_name1, file_name2, p_args):
    """
    Open the two database files and call the the internal difference function
    :param file_name1: file name 1
    :type file_name1: str
    :param file_name2: file name 2
    :type file_name2: str
    :param p_args: command line arguments
    :type p_args: Namespace
    :return:
    """
    if debug_flag:
        print('\n-- diff_databases', file_name1, file_name2)
    try:
        # f1 = open(file1, 'r')
        # f2 = open(file2, 'r')
        # diff_databases(f1, f2, file1, file2)
        my_filter = diff_filter if p_args.clean else None
        df1 = DatabaseFile(file_name=file_name1, filter_function=my_filter)
        df2 = DatabaseFile(file_name=file_name2, filter_function=my_filter)
        diff_databases(df1, df2, file_name1, file_name2)
        df1.close()
        df2.close()
    except (OSError, IOError) as ex:
        print(ex)
Beispiel #2
0
def sort_database(f, file_name, p_args):
    """
    This is the callback function for process_file_list.
    Read the database file and print the database sorted by record and field names.
    :param f: database file
    :type f: TextIOBase
    :param file_name: file name (needed, but not used)
    :type file_name: str
    :param p_args: command line arguments (not used)
    :type p_args: Namespace
    :return: None
    """
    if debug_flag:
        print('\n-- sort_database', f, file_name, p_args)
    df = DatabaseFile(f)
    db = df.read_database()
    assert (isinstance(db, EpicsDatabase))
    db.write_sorted_database(reverse=p_args.reverse)
    df.close()
    return
Beispiel #3
0
def list_records(f, file_name, p_args):
    """
    This is the callback function for process_file_list.
    It will get called once for each file in the input file list.
    List records in a database file.
    :param f: database file
    :param file_name: file name (not used)
    :param p_args: command line arguments
    :return: None
    """
    if debug_flag:
        print('\n--list_records', f, file_name, p_args)
    df = DatabaseFile(f)
    for record_name, record_type in df.next_record_name():
        if p_args.type:
            print(record_name + ', ' + record_type)
        else:
            print(record_name)
    df.close()
    return
Beispiel #4
0
def grep_file(f, file_name, p_args):
    """
    This routine looks for matches in the record name, record type, field name and/or field value.
    The command line options are used to select what type of matching is desired.
    The output will have a valid database syntax.
    :param f: database file
    :param file_name: database file name
    :param p_args: command line arguments
    :type p_args: Namespace
    """

    # Print debug information
    if debug_flag:
        print(file_name, p_args.pattern, file_name)

    # This variable is used to control whether the file name should be printed embedded in the
    # output database as a comment. When no matches are found no file name should be printed not
    # be printed to avoid unwanted output.
    more_than_one_file = True if len(p_args.files) > 1 else False

    # The following variable controls whether only the file name should be printed when a match is found
    # Flags to control the output
    file_name_only = p_args.filename

    # This variable is usd to control whether all the fields in a matching record
    # should be printed when a match is found.
    all_fields = p_args.all_fields

    if debug_flag:
        print('more_than_one_file, file_name_only =', more_than_one_file, file_name_only)

    # Compile the pattern to make sure that there are no errors in it.
    # This will speed up searches and will catch errors before processing files.
    try:
        p = re.compile(p_args.pattern, re.IGNORECASE if p_args.ignorecase else 0)
    except Exception as ex:
        print('Error while parsing regular expression', ex)
        return

    # Create the database file object
    df = DatabaseFile(f)
    if debug_flag:
        print(df)

    # Match field name or value?
    match_fields = p_args.field_name or p_args.field_value

    # Used to break out from two nested loops (Python doesn't have labeled breaks yet).
    break_out = False

    # Loop over all records in the file.
    # The records will be processed in the same order as in the file.
    for record in df.next_record():
        assert (isinstance(record, EpicsRecord))

        # This variable is used to determine whether the start of a record was printed or not.
        # We only need the record name once per record. A match in a field name or value will
        # print the record start if it was not printed already.
        record_start_printed = False

        # Get record and type
        record_name, record_type = record.get_name(), record.get_type()
        if debug_flag:
            print(record_name, record_type)

        # Check whether matching for record name and type is selected
        # Print the record header if there's a record match
        if (p_args.record_name and p.search(record_name)) or (p_args.record_type and p.search(record_type)):

            # Print the file name and stop looking for more matches
            if file_name_only:
                print(file_name)
                break

            # Print a file header as comment if there are more than one input files
            if more_than_one_file:
                print(file_name_header(file_name))
                more_than_one_file = False  # file name header was printed

            # Print the record start and mark it as printed
            print(format_record_start(record_name, record_type))
            record_start_printed = True  # record start was printed

            # If printing all fields then don't bother checking for matching fields
            if all_fields:
                print_all_fields(record)
                print(format_record_end())
                continue

        # Match fields?
        if match_fields:
            for field_name, field_value in record.get_fields():

                # Check matching for field name and/or value
                if (p_args.field_name and p.search(field_name)) or (p_args.field_value and p.search(field_value)):

                    # Print the file name and stop looking for more matches
                    if file_name_only:
                        print(file_name)
                        break_out = True  # stop record loop
                        break

                    # The record start and file header should be printed if it was done already.
                    if not record_start_printed:
                        if more_than_one_file:
                            print(file_name_header(file_name))
                            more_than_one_file = False  # file name was printed
                        print(format_record_start(record_name, record_type))
                        record_start_printed = True  # record start was printed

                    # If printing all fields then break the loop and continue with the next record
                    if all_fields:
                        print_all_fields(record)
                        break
                    else:
                        print(format_field(field_name, field_value))

            # Break out from the record loop
            if break_out:
                break

        # Print the record end if the start was printed
        if record_start_printed:
            print(format_record_end())

    df.close()

    return
Beispiel #5
0
def diff_files_external(file_name1, file_name2, p_args):
    """
    Open the two database files, sort them and call the external difference program.
    :param file_name1: file name 1
    :param file_name2: file name 2
    :param p_args: command line arguments
    :return: None
    """
    # Read databases into memory
    try:
        my_filter = diff_filter if p_args.clean else None
        df1 = DatabaseFile(file_name=file_name1, filter_function=my_filter)
        df2 = DatabaseFile(file_name=file_name2, filter_function=my_filter)
        db1 = df1.read_database()
        db2 = df2.read_database()
        df1.close()
        df2.close()
    except (OSError, IOError) as ex:
        print(ex)
        return

    # Create output file names by appending a time stamp
    time_stamp = str(int(time.time()))
    output_file_name1 = os.path.join(
        TEMP_DIRECTORY,
        os.path.basename(file_name1) + '_' + time_stamp + '_1')
    output_file_name2 = os.path.join(
        TEMP_DIRECTORY,
        os.path.basename(file_name2) + '_' + time_stamp + '_2')

    # Write the sorted databases to disk
    for db, file_name in [(db1, output_file_name1), (db2, output_file_name2)]:
        # print db, file_name
        assert (isinstance(db, EpicsDatabase))
        try:
            f = open(file_name, 'w')
            db.write_sorted_database(f_out=f)
            f.close()
        except (OSError, IOError) as ex:
            print(ex)
            return

    # Call external program to diff the files
    external_program = p_args.program[0]
    print('calling', external_program, 'with', output_file_name1, 'and',
          output_file_name2)
    try:
        subprocess.call(
            [external_program, output_file_name1, output_file_name2])
    except subprocess.CalledProcessError as ex:
        print('error while calling' + external_program)
        print(ex)

    # Remove temporary files
    try:
        os.remove(output_file_name1)
        os.remove(output_file_name2)
    except OSError as ex:
        print(ex)

    return