Пример #1
0
def getrpnftndoc(filename):
    """Extract in a list of dictionaries the parsed RPN style doc string
    of a Fortran file, one dic per sub or fn of prog

    getrpnftndoc(filename)
    """

    #Define regex
    refunc = re.compile(r'^\s+([a-zA-Z][a-zA-Z0-9_*]+\s+function)\s+([a-zA-Z][a-zA-Z0-9_]+).*',re.I)
    resub = re.compile(r'^\s+(subroutine|program)\s+([a-zA-Z][a-zA-Z0-9_]+).*',re.I)
    retag = re.compile(r'^[*!]([a-zA-Z]+).*',re.I)
    rebgn = re.compile(r'^[*!]\*\*([a-zA-Z].*)',re.I)
    reend = re.compile(r'^[*!]\*.*',re.I)

    ignorelist = [
        re.compile(r'^#include\s+<model_macros_f\.h>',re.I),
        re.compile(r'^#include\s+[\'"]impnone.cdk[\'"]',re.I),
        re.compile(r'^\*[cv]dir\s+',re.I),
        re.compile(r'^(\*|\s*!)?\s*$',re.I)
    ]

    #read file
    fsock = openAnything(filename)
    a = fsock.read()
    mylist = a.splitlines()

    #initialize var for loop
    indoc = False
    insec = None
    counter = 0
    linecounter = 0
    mydocdic = [{
        'filename':filename,
        'subname':'',
        'startline':0,
        'all':''
        },
    ]

    #loop through lines
    for myline in mylist:
        linecounter += 1
        keepline = True
        ignore = False
        for reitem in ignorelist:
            if re.search(reitem,myline,re.I):
                ignore = True
        if indoc and not ignore:
            mydocdic[counter]['all'] += myline+"\n"
            if re.search(retag,myline,re.I):
                insec = (re.sub(retag,r'\1',myline)).lower()
                keepline = False
            elif re.search(resub,myline,re.I):
                insec = 'main'
                mydocdic[counter]['subname'] = \
                    re.sub(resub,r'\2',myline)
                mydocdic[counter]['startline'] = linecounter
            elif re.search(refunc,myline,re.I):
                insec = 'main'
                mydocdic[counter]['subname'] = \
                    re.sub(refunc,r'\2',myline)
                mydocdic[counter]['startline'] = linecounter
            #elif re.search(r'^\s+',myline): #code line
            #    pass
            elif re.search(r'^[*cC!]\s+\W+',myline): #in section comment line
                pass
            elif re.search(r'^[^*cC!]\s*\W+',myline): #code line
                pass
            elif re.search(reend,myline): #end of doc section
                indoc = False
                keepline = False
            if insec and keepline:
                if insec in mydocdic[counter].keys():
                    mydocdic[counter][insec] += str(myline)+"\n"
                else:
                    mydocdic[counter][insec] = myline+"\n"
        elif re.search(rebgn,myline):
            indoc = True
            insec = 'title'
            mydocdic[counter]['all'] += myline+"\n"
            mydocdic[counter][insec] = myline+"\n"
            #if len(subsecs)<1 or insec in subsecs:
            #    print insec,myline
    return mydocdic
Пример #2
0
def tidy_f90(filename):
    """echo a tidy up version of a f90 program

    tidy_f90(filename)
    """
    
    emptypattern = [
        # - merge multiple empty lines (empty comment == empty line)
        (r'\n[ \t]*![ \t]*\n',"\n\n"),
        (r'\n([ \t]*\n)+',    "\n\n")
        ]
        
    #Define regex
    patternlist = [
        # - remove trailing blanks
        (r'[ \t]+\n',         "\n"),
        # - remove extra head blanks in comments (more than 3)
        (r'\n[ \t]*![ \t][ \t][ \t]+',"\n!   "),
        # - remove extra spaces around parentesis [except after if]
        (r'[ \t]*\([ \t]*',   "("),
        (r'[ \t]*\)',         ")"),
        (r'if\(',             "if ("),
        # - max one space after comma (none before)
        (r'[ \t]+,',          ","),    #TODO: should not catch '\n[ \t]+\('
        (r',[ \t]+',          ", "),
        # - at least one space before trailing &
        (r'&[ \t]*\n',        " &\n"),  #TODO: should not add one if there
        # - update doc format
        (r'!author','!@author'),
        (r'!revision','!@revisions'),
        (r'!arguments','!@arguments'),
        (r'!object','!@description'),
        (r'\n!\*\*[ \t]*s/r[ \t]*','\n!/**\n!@objective'),
        (r'\n!\*[ \t]*\n','\n!**/\n'),
        # - misc
        (r'end[ \t]+do','enddo'),
        (r'end[ \t]+if','endif'),
        (r'else[ \t]+if','elseif')
        ]

    # - replace .eq. (and other) notation, one space around, lowercase
    oprlist = [ (r'\.eq\.',r'=='),
                (r'\.ne\.',r'/='),
                (r'\.gt\.',r'>'),
                (r'\.ge\.',r'>='),
                (r'\.lt\.',r'<'),
                (r'\.le\.',r'<=')
                ]

    postfixlist = [ (r'\b[ \t]*\.or\.[ \t]*\b',' .or. '),
                    (r'\b[ \t]*\.and\.[ \t]*\b',' .and. '),
                    (r'[ \t]*=[ \t]*',' = '),
                    (r'\b\([ \t]*len[ \t]*=[ \t]*\b','(len='),
                    (r'\b\([ \t]*kind[ \t]*=[ \t]*\b','(kind='),
                    (r'= +=','=='),
                    (r'/ +=','/='),
                    (r'> +=','>='),
                    (r'< +=','<='),
                    (r'= +>','=>')
                    ]

    pattern = []
    replace = []
    
    for (opr1,opr2) in patternlist:
        pattern.append(re.compile(opr1,re.I))
        replace.append(opr2)
    
    for (opr1,opr2) in oprlist:
        pattern.append(re.compile(opr1,re.I))
        replace.append(opr2)
        
    # - one and only on space around = and other operators
    for (opr1,opr2) in oprlist: #TODO:not in comments/string
        pattern.append(re.compile(r'[ \t]*'+opr2+r'[ \t]*',re.I))
        replace.append(' '+opr2+' ')

    
    for (opr1,opr2) in postfixlist:
        pattern.append(re.compile(opr1,re.I))
        replace.append(opr2)
        pattern.append(re.compile(opr1,re.I))
        replace.append(opr2)
        pattern.append(re.compile(opr1,re.I))
        replace.append(opr2)
        
        
    #read file
    fsock = openAnything(filename)
    myfilestr = fsock.read()

    #s = re.sub("(?<= )(.+)(?= )", lambda m: "can use a callable for the %s text too" % m.group(1), s)
    #print(re.sub(pattern,replace,myfilestr))

    (myfilestr,commentlist,stringslist) = pull_comm_str(myfilestr)

    i = 0
    for mypatt in pattern:
        myfilestr = re.sub(mypatt,replace[i],myfilestr)
        i=i+1

    myfilestr = indent_f90(myfilestr)

    myfilestr = push_comm_str(myfilestr,commentlist,stringslist)

    pattern = []
    replace = []
    for (opr1,opr2) in emptypattern:
        pattern.append(re.compile(opr1,re.I))
        replace.append(opr2)
 
    i = 0
    for mypatt in pattern:
        myfilestr = re.sub(mypatt,replace[i],myfilestr)
        i=i+1
        
    #TODO:
    # - replace licence
    # - last end should with function/sub name
    # - lower case [but not parameters]
    # - external and parameters... now attributes
    # - split too long lines
    # - add () on subroutine name and call sub when missing

    return myfilestr