xref: /minix3/external/bsd/llvm/dist/llvm/utils/llvm-build/llvmbuild/configutil.py (revision f4a2713ac843a11c696ec80c0a5e3e5d80b4d338)
1*f4a2713aSLionel Sambuc"""
2*f4a2713aSLionel SambucDefines utilities useful for performing standard "configuration" style tasks.
3*f4a2713aSLionel Sambuc"""
4*f4a2713aSLionel Sambuc
5*f4a2713aSLionel Sambucimport re
6*f4a2713aSLionel Sambucimport os
7*f4a2713aSLionel Sambuc
8*f4a2713aSLionel Sambucdef configure_file(input_path, output_path, substitutions):
9*f4a2713aSLionel Sambuc    """configure_file(input_path, output_path, substitutions) -> bool
10*f4a2713aSLionel Sambuc
11*f4a2713aSLionel Sambuc    Given an input and output path, "configure" the file at the given input path
12*f4a2713aSLionel Sambuc    by replacing variables in the file with those given in the substitutions
13*f4a2713aSLionel Sambuc    list. Returns true if the output file was written.
14*f4a2713aSLionel Sambuc
15*f4a2713aSLionel Sambuc    The substitutions list should be given as a list of tuples (regex string,
16*f4a2713aSLionel Sambuc    replacement), where the regex and replacement will be used as in 're.sub' to
17*f4a2713aSLionel Sambuc    execute the variable replacement.
18*f4a2713aSLionel Sambuc
19*f4a2713aSLionel Sambuc    The output path's parent directory need not exist (it will be created).
20*f4a2713aSLionel Sambuc
21*f4a2713aSLionel Sambuc    If the output path does exist and the configured data is not different than
22*f4a2713aSLionel Sambuc    it's current contents, the output file will not be modified. This is
23*f4a2713aSLionel Sambuc    designed to limit the impact of configured files on build dependencies.
24*f4a2713aSLionel Sambuc    """
25*f4a2713aSLionel Sambuc
26*f4a2713aSLionel Sambuc    # Read in the input data.
27*f4a2713aSLionel Sambuc    f = open(input_path, "rb")
28*f4a2713aSLionel Sambuc    try:
29*f4a2713aSLionel Sambuc        data = f.read()
30*f4a2713aSLionel Sambuc    finally:
31*f4a2713aSLionel Sambuc        f.close()
32*f4a2713aSLionel Sambuc
33*f4a2713aSLionel Sambuc    # Perform the substitutions.
34*f4a2713aSLionel Sambuc    for regex_string,replacement in substitutions:
35*f4a2713aSLionel Sambuc        regex = re.compile(regex_string)
36*f4a2713aSLionel Sambuc        data = regex.sub(replacement, data)
37*f4a2713aSLionel Sambuc
38*f4a2713aSLionel Sambuc    # Ensure the output parent directory exists.
39*f4a2713aSLionel Sambuc    output_parent_path = os.path.dirname(os.path.abspath(output_path))
40*f4a2713aSLionel Sambuc    if not os.path.exists(output_parent_path):
41*f4a2713aSLionel Sambuc        os.makedirs(output_parent_path)
42*f4a2713aSLionel Sambuc
43*f4a2713aSLionel Sambuc    # If the output path exists, load it and compare to the configured contents.
44*f4a2713aSLionel Sambuc    if os.path.exists(output_path):
45*f4a2713aSLionel Sambuc        current_data = None
46*f4a2713aSLionel Sambuc        try:
47*f4a2713aSLionel Sambuc            f = open(output_path, "rb")
48*f4a2713aSLionel Sambuc            try:
49*f4a2713aSLionel Sambuc                current_data = f.read()
50*f4a2713aSLionel Sambuc            except:
51*f4a2713aSLionel Sambuc                current_data = None
52*f4a2713aSLionel Sambuc            f.close()
53*f4a2713aSLionel Sambuc        except:
54*f4a2713aSLionel Sambuc            current_data = None
55*f4a2713aSLionel Sambuc
56*f4a2713aSLionel Sambuc        if current_data is not None and current_data == data:
57*f4a2713aSLionel Sambuc            return False
58*f4a2713aSLionel Sambuc
59*f4a2713aSLionel Sambuc    # Write the output contents.
60*f4a2713aSLionel Sambuc    f = open(output_path, "wb")
61*f4a2713aSLionel Sambuc    try:
62*f4a2713aSLionel Sambuc        f.write(data)
63*f4a2713aSLionel Sambuc    finally:
64*f4a2713aSLionel Sambuc        f.close()
65*f4a2713aSLionel Sambuc
66*f4a2713aSLionel Sambuc    return True
67