#!/usr/bin/env python

import re

#========================================================================================
blank_pat = re.compile(r'^\s*$')
com_pat = re.compile(r'^\s*!$')
def_pat = re.compile(r'^\s*(type|integer|real|complex|logical|character)', re.I)

class docZoom:

    def __init__(self, symbol, filename):

        self.symbol = symbol
        self.data = {'what': '',
                     'args': '',
                     'defs': '',
                     }
        
        sym_re = re.compile(
            r'^\s*(?P<what>module|type|subroutine|function)\s+%s\s*(?P<args>[\w\d_,\s\(\)]*)'
            %symbol, re.I)
        end_re = re.compile(r'^\s*end\s*(module|type|subroutine|function)\s*\b%s\b'%
                            symbol, re.I)
        def_flag = 0
        for line in file(filename, 'r').readlines():
            if def_flag:
                pat = re.match(end_re, line)
                if pat: def_flag = 0
            if def_flag:
                if re.match(com_pat, line):
                    # keep comments
                    self.data['defs'] += line
                elif re.match(def_pat, line):
                    # look for def of arguments
                    la = re.sub(r'\s','', self.data['args'])
                    la = re.sub(r'\(','', la)
                    la = re.sub(r'\)','', la)                    
                    for a in la.split(','):
                        if a in line:
                            self.data['defs'] += line

            pat = re.match(sym_re, line)
            if pat:
                self.data['what'] = pat.group('what') 
                self.data['args'] = pat.group('args') 
                def_flag = 1 

    def out(self):
        print '\n'
        print self.data['what'].upper() +' '+self.symbol + self.data['args']
        print self.data['defs']

#========================================================================================

module_re = re.compile(r'^\s*module\s+(?P<name>\b[\w_\d]+\b)\s*!?.*?$', re.I)
program_re = re.compile(r'^\s*program\s+(?P<name>\b[\w_\d]+\b)\s*!?.*?$', re.I)
type_re = re.compile(r'^\s*type\s+(?P<name>\b[\w_\d]+\b)\s*!?.*?$', re.I)
subroutine_re = re.compile(r'^\s*subroutine\s+(?P<name>\b[\w_\d\(\),\s]+)\s*!?.*?$', re.I)
function_re = re.compile(r'^\s*function\s+(?P<name>\b[\w_\d\(\),\s]+)\s*!?.*?$', re.I)

all_re = {
    'module': module_re,
    'program': program_re,
    'type': type_re,
    'subroutine': subroutine_re,
    'function': function_re,
    }


class docTree:

    def __init__(self, file):

        self.data = {}

        self.file = file
        module_name = ''
        for line in open(file, 'r').readlines():
            for pat_key in all_re:
                pat = re.match(all_re[pat_key], line)
                if pat:
                    if pat_key=='module' or pat_key=='program':
                        module_name = pat.group('name')
                        self.data[module_name] = {'type': [],
                                                  'subroutine': [],
                                                  'function': [],
                                                  }
                    else:
                        self.data[module_name][pat_key].append(pat.group('name'))

    def out(self):

        print '\n'
        for m in self.data:
            print 'MODULE ', m
            for t in self.data[m]['type']:
                print '\tTYPE ', t
            for s in self.data[m]['subroutine']:
                print '\t\tSUBROUTINE', s
            for f in self.data[m]['function']:
                print '\t\tFUNCTION', f
        
    def ascii(self):
        print self.data
        

##    def html(self):

    



#.............................................................................

if __name__=='__main__':

    import sys

    s = None
    f = None
    if len(sys.argv) <= 1:
        print sys.argv[0],' [options] filename'
        print 'options: "symbol" a subroutine or function name.'     
        sys.exit(1)

    elif len(sys.argv)==2:
        f = sys.argv[1]
        d = docTree(f)
        d.out()
    else:
        s = sys.argv[1]
        f = sys.argv[2]
        d = docZoom(s, f)
        d.out()
