1# Check for a module in a set of extension directories.
2# An extension directory should contain a Setup file
3# and one or more .o files or a lib.a file.
4
5import os
6import parsesetup
7
8def checkextensions(unknown, extensions):
9    files = []
10    modules = []
11    edict = {}
12    for e in extensions:
13        setup = os.path.join(e, 'Setup')
14        liba = os.path.join(e, 'lib.a')
15        if not os.path.isfile(liba):
16            liba = None
17        edict[e] = parsesetup.getsetupinfo(setup), liba
18    for mod in unknown:
19        for e in extensions:
20            (mods, vars), liba = edict[e]
21            if mod not in mods:
22                continue
23            modules.append(mod)
24            if liba:
25                # If we find a lib.a, use it, ignore the
26                # .o files, and use *all* libraries for
27                # *all* modules in the Setup file
28                if liba in files:
29                    break
30                files.append(liba)
31                for m in list(mods.keys()):
32                    files = files + select(e, mods, vars,
33                                           m, 1)
34                break
35            files = files + select(e, mods, vars, mod, 0)
36            break
37    return files, modules
38
39def select(e, mods, vars, mod, skipofiles):
40    files = []
41    for w in mods[mod]:
42        w = treatword(w)
43        if not w:
44            continue
45        w = expandvars(w, vars)
46        for w in w.split():
47            if skipofiles and w[-2:] == '.o':
48                continue
49            # Assume $var expands to absolute pathname
50            if w[0] not in ('-', '$') and w[-2:] in ('.o', '.a'):
51                w = os.path.join(e, w)
52            if w[:2] in ('-L', '-R') and w[2:3] != '$':
53                w = w[:2] + os.path.join(e, w[2:])
54            files.append(w)
55    return files
56
57cc_flags = ['-I', '-D', '-U']
58cc_exts = ['.c', '.C', '.cc', '.c++']
59
60def treatword(w):
61    if w[:2] in cc_flags:
62        return None
63    if w[:1] == '-':
64        return w # Assume loader flag
65    head, tail = os.path.split(w)
66    base, ext = os.path.splitext(tail)
67    if ext in cc_exts:
68        tail = base + '.o'
69        w = os.path.join(head, tail)
70    return w
71
72def expandvars(str, vars):
73    i = 0
74    while i < len(str):
75        i = k = str.find('$', i)
76        if i < 0:
77            break
78        i = i+1
79        var = str[i:i+1]
80        i = i+1
81        if var == '(':
82            j = str.find(')', i)
83            if j < 0:
84                break
85            var = str[i:j]
86            i = j+1
87        if var in vars:
88            str = str[:k] + vars[var] + str[i:]
89            i = k
90    return str
91