17db96d56Sopenharmony_ci# Parse Makefiles and Python Setup(.in) files.
27db96d56Sopenharmony_ci
37db96d56Sopenharmony_ciimport re
47db96d56Sopenharmony_ci
57db96d56Sopenharmony_ci
67db96d56Sopenharmony_ci# Extract variable definitions from a Makefile.
77db96d56Sopenharmony_ci# Return a dictionary mapping names to values.
87db96d56Sopenharmony_ci# May raise IOError.
97db96d56Sopenharmony_ci
107db96d56Sopenharmony_cimakevardef = re.compile('^([a-zA-Z0-9_]+)[ \t]*=(.*)')
117db96d56Sopenharmony_ci
127db96d56Sopenharmony_cidef getmakevars(filename):
137db96d56Sopenharmony_ci    variables = {}
147db96d56Sopenharmony_ci    fp = open(filename)
157db96d56Sopenharmony_ci    pendingline = ""
167db96d56Sopenharmony_ci    try:
177db96d56Sopenharmony_ci        while 1:
187db96d56Sopenharmony_ci            line = fp.readline()
197db96d56Sopenharmony_ci            if pendingline:
207db96d56Sopenharmony_ci                line = pendingline + line
217db96d56Sopenharmony_ci                pendingline = ""
227db96d56Sopenharmony_ci            if not line:
237db96d56Sopenharmony_ci                break
247db96d56Sopenharmony_ci            if line.endswith('\\\n'):
257db96d56Sopenharmony_ci                pendingline = line[:-2]
267db96d56Sopenharmony_ci            matchobj = makevardef.match(line)
277db96d56Sopenharmony_ci            if not matchobj:
287db96d56Sopenharmony_ci                continue
297db96d56Sopenharmony_ci            (name, value) = matchobj.group(1, 2)
307db96d56Sopenharmony_ci            # Strip trailing comment
317db96d56Sopenharmony_ci            i = value.find('#')
327db96d56Sopenharmony_ci            if i >= 0:
337db96d56Sopenharmony_ci                value = value[:i]
347db96d56Sopenharmony_ci            value = value.strip()
357db96d56Sopenharmony_ci            variables[name] = value
367db96d56Sopenharmony_ci    finally:
377db96d56Sopenharmony_ci        fp.close()
387db96d56Sopenharmony_ci    return variables
397db96d56Sopenharmony_ci
407db96d56Sopenharmony_ci
417db96d56Sopenharmony_ci# Parse a Python Setup(.in) file.
427db96d56Sopenharmony_ci# Return two dictionaries, the first mapping modules to their
437db96d56Sopenharmony_ci# definitions, the second mapping variable names to their values.
447db96d56Sopenharmony_ci# May raise IOError.
457db96d56Sopenharmony_ci
467db96d56Sopenharmony_cisetupvardef = re.compile('^([a-zA-Z0-9_]+)=(.*)')
477db96d56Sopenharmony_ci
487db96d56Sopenharmony_cidef getsetupinfo(filename):
497db96d56Sopenharmony_ci    modules = {}
507db96d56Sopenharmony_ci    variables = {}
517db96d56Sopenharmony_ci    fp = open(filename)
527db96d56Sopenharmony_ci    pendingline = ""
537db96d56Sopenharmony_ci    try:
547db96d56Sopenharmony_ci        while 1:
557db96d56Sopenharmony_ci            line = fp.readline()
567db96d56Sopenharmony_ci            if pendingline:
577db96d56Sopenharmony_ci                line = pendingline + line
587db96d56Sopenharmony_ci                pendingline = ""
597db96d56Sopenharmony_ci            if not line:
607db96d56Sopenharmony_ci                break
617db96d56Sopenharmony_ci            # Strip comments
627db96d56Sopenharmony_ci            i = line.find('#')
637db96d56Sopenharmony_ci            if i >= 0:
647db96d56Sopenharmony_ci                line = line[:i]
657db96d56Sopenharmony_ci            if line.endswith('\\\n'):
667db96d56Sopenharmony_ci                pendingline = line[:-2]
677db96d56Sopenharmony_ci                continue
687db96d56Sopenharmony_ci            matchobj = setupvardef.match(line)
697db96d56Sopenharmony_ci            if matchobj:
707db96d56Sopenharmony_ci                (name, value) = matchobj.group(1, 2)
717db96d56Sopenharmony_ci                variables[name] = value.strip()
727db96d56Sopenharmony_ci            else:
737db96d56Sopenharmony_ci                words = line.split()
747db96d56Sopenharmony_ci                if words:
757db96d56Sopenharmony_ci                    modules[words[0]] = words[1:]
767db96d56Sopenharmony_ci    finally:
777db96d56Sopenharmony_ci        fp.close()
787db96d56Sopenharmony_ci    return modules, variables
797db96d56Sopenharmony_ci
807db96d56Sopenharmony_ci
817db96d56Sopenharmony_ci# Test the above functions.
827db96d56Sopenharmony_ci
837db96d56Sopenharmony_cidef test():
847db96d56Sopenharmony_ci    import sys
857db96d56Sopenharmony_ci    import os
867db96d56Sopenharmony_ci    if not sys.argv[1:]:
877db96d56Sopenharmony_ci        print('usage: python parsesetup.py Makefile*|Setup* ...')
887db96d56Sopenharmony_ci        sys.exit(2)
897db96d56Sopenharmony_ci    for arg in sys.argv[1:]:
907db96d56Sopenharmony_ci        base = os.path.basename(arg)
917db96d56Sopenharmony_ci        if base[:8] == 'Makefile':
927db96d56Sopenharmony_ci            print('Make style parsing:', arg)
937db96d56Sopenharmony_ci            v = getmakevars(arg)
947db96d56Sopenharmony_ci            prdict(v)
957db96d56Sopenharmony_ci        elif base[:5] == 'Setup':
967db96d56Sopenharmony_ci            print('Setup style parsing:', arg)
977db96d56Sopenharmony_ci            m, v = getsetupinfo(arg)
987db96d56Sopenharmony_ci            prdict(m)
997db96d56Sopenharmony_ci            prdict(v)
1007db96d56Sopenharmony_ci        else:
1017db96d56Sopenharmony_ci            print(arg, 'is neither a Makefile nor a Setup file')
1027db96d56Sopenharmony_ci            print('(name must begin with "Makefile" or "Setup")')
1037db96d56Sopenharmony_ci
1047db96d56Sopenharmony_cidef prdict(d):
1057db96d56Sopenharmony_ci    keys = sorted(d.keys())
1067db96d56Sopenharmony_ci    for key in keys:
1077db96d56Sopenharmony_ci        value = d[key]
1087db96d56Sopenharmony_ci        print("%-15s" % key, str(value))
1097db96d56Sopenharmony_ci
1107db96d56Sopenharmony_ciif __name__ == '__main__':
1117db96d56Sopenharmony_ci    test()
112