def parse_metadata_file(cls, filename):
     "Parse <filename> and return list of parsed metadata headers"
     # Read all lines of the file at once
     mheaders = list()
     with open(filename, 'r') as file:
         fin_lines = file.readlines()
         for index in range(len(fin_lines)):
             fin_lines[index] = fin_lines[index].rstrip('\n')
         # End for
     # End with
     # Look for a header start
     parse_obj = ParseObject(filename, fin_lines)
     curr_line, curr_line_num = parse_obj.curr_line()
     while curr_line is not None:
         if MetadataHeader.table_start(curr_line):
             if '[ccpp-table-properties]' in curr_line:
                 mheaders.append(
                     MetadataHeader(parse_obj, property_table=True))
             else:
                 mheaders.append(MetadataHeader(parse_obj))
             curr_line, curr_line_num = parse_obj.curr_line()
         else:
             curr_line, curr_line_num = parse_obj.next_line()
         # End if
     # End while
     return mheaders
Example #2
0
def read_file(filename, preproc_defs=None, logger=None):
    """Read a file into an array of lines.
    Preprocess lines to consolidate continuation lines.
    Remove preprocessor directives and code eliminated by #if statements
    Remvoved code results in blank lines, not removed lines
    """
    preproc_status = PreprocStack()
    if not os.path.exists(filename):
        raise IOError("read_file: file, '{}', does not exist".format(filename))
    else:
        # We need special rules for fixed-form source
        fixed_form = filename[-2:].lower() == '.f'
        # Read all lines of the file at once
        with open(filename, 'r') as file:
            file_lines = file.readlines()
            for index in xrange(len(file_lines)):
                file_lines[index] = file_lines[index].rstrip('\n').rstrip()
            # End for
        # End with
        # create a parse object and context for this file
        pobj = ParseObject(filename, file_lines)
        continue_col = -1  # Active continue column
        in_schar = False  # Single quote character context
        in_dchar = False  # Double quote character context
        prev_line = None
        prev_line_num = -1
        curr_line, curr_line_num = pobj.curr_line()
        while curr_line is not None:
            # Skip empty lines and comment-only lines
            skip_line = False
            if len(curr_line.strip()) == 0:
                skip_line = True
            elif fixed_form and (fixed_comment_re.match(curr_line)
                                 is not None):
                skip_line = True
            elif curr_line.lstrip()[0] == '!':
                skip_line = True
            # End if
            if skip_line:
                curr_line, curr_line_num = pobj.next_line()
                continue
            # End if
            # Handle preproc issues
            if preproc_status.process_line(curr_line, preproc_defs, pobj,
                                           logger):
                pobj.write_line(curr_line_num, "")
                curr_line, curr_line_num = pobj.next_line()
                continue
            # End if
            if not preproc_status.in_true_region():
                # Special case to allow CCPP comment statements in False
                # regions to find DDT and module table code
                if (curr_line[0:2] != '!!') and (curr_line[0:2] != '!>'):
                    pobj.write_line(curr_line_num, "")
                    curr_line, curr_line_num = pobj.next_line()
                    continue
                # End if
            # End if
            # scan the line for properties
            if fixed_form:
                res = scan_fixed_line(curr_line, in_schar, in_dchar, pobj)
                cont_in_col, in_schar, in_dchar, comment_col = res
                continue_col = cont_in_col  # No warning in fixed form
                cont_out_col = -1
                if (comment_col < 0) and (continue_col < 0):
                    # Real statement, grab the line # in case is continued
                    prev_line_num = curr_line_num
                    prev_line = None
                # End if
            else:
                res = scan_free_line(curr_line, (continue_col >= 0), in_schar,
                                     in_dchar, pobj)
                cont_in_col, cont_out_col, in_schar, in_dchar, comment_col = res
            # End if
            # If in a continuation context, move this line to previous
            if continue_col >= 0:
                if fixed_form and (prev_line is None):
                    prev_line = pobj.peek_line(prev_line_num)[0:72]
                # End if
                if prev_line is None:
                    raise ParseInternalError("No prev_line to continue",
                                             context=pobj)
                # End if
                sindex = max(cont_in_col + 1, 0)
                if fixed_form:
                    sindex = 6
                    eindex = 72
                elif cont_out_col > 0:
                    eindex = cont_out_col
                else:
                    eindex = len(curr_line)
                # End if
                prev_line = prev_line + curr_line[sindex:eindex]
                if fixed_form:
                    prev_line = prev_line.rstrip()
                # End if
                # Rewrite the file's lines
                pobj.write_line(prev_line_num, prev_line)
                pobj.write_line(curr_line_num, "")
                if (not fixed_form) and (cont_out_col < 0):
                    # We are done with this line, reset prev_line
                    prev_line = None
                    prev_line_num = -1
                # End if
            # End if
            continue_col = cont_out_col
            if (continue_col >= 0) and (prev_line is None):
                # We need to set up prev_line as it is continued
                prev_line = curr_line[0:continue_col]
                if not (in_schar or in_dchar):
                    prev_line = prev_line.rstrip()
                # End if
                prev_line_num = curr_line_num
            # End if
            curr_line, curr_line_num = pobj.next_line()
        # End while
        return pobj