]> rtime.felk.cvut.cz Git - linux-conf-perf.git/blob - scripts/configurations.py
722aaafcd7093117a29cae384cb8b4b2cc2758d9
[linux-conf-perf.git] / scripts / configurations.py
1 import os
2 import sys
3 import tempfile
4 import subprocess
5 import time
6
7 import utils
8 from conf import conf
9 from conf import sf
10 import exceptions
11
12 def generate():
13         """Collect boolean equations from files: rules, solved and required
14         And get solution with picosat
15         """
16         # Check if rules_file exist. If it was generated.
17         if not os.path.isfile(sf(conf.rules_file)):
18                 raise exceptions.MissingFile(conf.rules_file,"Run parse_kconfig.")
19
20         if os.path.isfile(sf(conf.solution_file)):
21                 raise exceptions.SolutionGenerated()
22
23         w_file = tempfile.NamedTemporaryFile(delete=False)
24         # Join files to one single temporary file
25         lines = set()
26         with open(sf(conf.rules_file), 'r') as f:
27                 for lnn in open(sf(conf.rules_file), 'r'):
28                         ln = lnn.rstrip()
29                         if ln not in lines:
30                                 lines.add(ln)
31         if os.path.isfile(sf(conf.required_file)):
32                 for lnn in open(sf(conf.required_file), 'r'):
33                         ln = lnn.rstrip()
34                         if ln not in lines:
35                                 lines.add(ln)
36
37         with open(sf(conf.variable_count_file)) as f:
38                 var_num = f.readline()
39         lines_count = len(lines)
40
41         first_line = "p cnf " + var_num + " " + str(lines_count)
42         w_file.write(bytes(first_line + '\n', 'UTF-8'))
43         for ln in lines:
44                 w_file.write(bytes(ln + ' 0\n', 'UTF-8'))
45
46         w_file.close()
47
48         # Execute picosat
49         try:
50                 os.mkdir(sf(conf.log_folder))
51         except OSError:
52                 pass
53
54         picosat_cmd = [sf(conf.picosat), w_file.name]
55         picosat_cmd += conf.picosat_args
56
57         satprc = subprocess.Popen(picosat_cmd, stdout = subprocess.PIPE)
58         with open(os.path.join(sf(conf.log_folder), "picosat.log"), 'a') as f:
59                 f.write("::" + time.strftime("%y-%m-%d-%H-%M-%S") + "::\n")
60                 solut = []
61                 for linen in satprc.stdout:
62                         line = linen.decode(sys.getdefaultencoding())
63                         f.write(line)
64                         if conf.picosat_output:
65                                 print(line, end="")
66                         if line[0] == 's':
67                                 try:
68                                         solut.remove(0)
69                                         with open(sf(conf.config_map_file), 'a') as fm:
70                                                 fm.write(str(utils.hash_config(solut)) + ':')
71                                                 for sl in solut:
72                                                         fm.write(str(sl) + ' ')
73                                                 fm.write('\n')
74                                 except ValueError:
75                                         pass
76                                 solut = []
77                                 if not line.rstrip() == 's SATISFIABLE':
78                                         os.remove(w_file.name)
79                                         raise exceptions.NoSolution()
80                         elif line[0] == 'v':
81                                 for sl in line[2:].split():
82                                         solut.append(int(sl))
83
84         os.remove(w_file.name)
85
86 def apply():
87         """Apply generated solution to kernel source.
88         """
89         utils.build_symbol_map() # Ensure smap existence
90
91         solved = set()
92         solution = []
93         # Load set of solved solutions
94         if os.path.isfile(sf(conf.config_solved_file)):
95                 with open(sf(conf.config_solved_file)) as f:
96                         for ln in f:
97                                 solved.add(ln.strip())
98
99         # Load one solution if it is not in solved
100         hash = ''
101         with open(sf(conf.config_map_file)) as f:
102                         while True:
103                                 w = f.readline().split(sep=':')
104                                 if not w[0]:
105                                         break
106                                 if not w[0] in solved:
107                                         solution = utils.config_strtoint(w[1], True)
108                                         hash = w[0]
109                                         break
110         if not solution:
111                 raise exceptions.NoApplicableSolution()
112
113         # Write hash to config_solved
114         with open(sf(conf.config_solved_file), 'a') as f:
115                 f.write(hash)
116                 f.write('\n')
117
118         # Load variable count
119         with open(sf(conf.symbol_map_file)) as f:
120                 for var_num, l in enumerate(f):
121                         pass
122                 var_num += 1
123         # Write solution to .config file in linux source folder
124         with open(sf(conf.linux_dot_config), 'w') as f:
125                 for s in solution:
126                         if s < 0:
127                                 nt = True
128                                 s *= -1
129                         else:
130                                 nt = False
131                         if s >= var_num:
132                                 break;
133                         if 'NONAMEGEN' in utils.smap[s]: # ignore generated names
134                                 continue
135
136                         f.write('CONFIG_' + utils.smap[s] + '=')
137                         if not nt:
138                                 f.write('y')
139                         else:
140                                 f.write('n')
141                         f.write('\n')