aboutsummaryrefslogtreecommitdiff
path: root/scripts/solution.py
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/solution.py')
-rw-r--r--scripts/solution.py108
1 files changed, 61 insertions, 47 deletions
diff --git a/scripts/solution.py b/scripts/solution.py
index 8e02324..f9f605b 100644
--- a/scripts/solution.py
+++ b/scripts/solution.py
@@ -2,6 +2,7 @@ import os
import sys
import tempfile
import subprocess
+import time
import utils
from conf import conf
@@ -16,7 +17,7 @@ def generate():
if not os.path.isfile(sf(conf.rules_file)):
raise exceptions.MissingFile(conf.rules_file,"Run parse_kconfig.")
- if sys.path.isfile(sf(conf.solution_file)) and conf.gen_all_solution_oninit:
+ if os.path.isfile(sf(conf.solution_file)) and conf.gen_all_solution_oninit:
raise exceptions.SolutionGenerated()
w_file = tempfile.NamedTemporaryFile(delete=False)
@@ -50,56 +51,69 @@ def generate():
w_file.close()
# Execute picosat
- picosat_cmd = [conf.picosat, w_file.name]
- picosat_cmd += ['-o', sf(conf.solution_file)]
+ try:
+ os.mkdir(sf(conf.log_folder))
+ except OSError:
+ pass
+
+ picosat_cmd = [sf(conf.picosat), w_file.name]
if (conf.gen_all_solution_oninit):
picosat_cmd += ['--all']
- if conf.picosat_output:
- subprocess.call(picosat_cmd)
- else:
- subprocess.call(picosat_cmd, stdout=subprocess.DEVNULL)
+
+ satprc = subprocess.Popen(picosat_cmd, stdout = subprocess.PIPE)
+ with open(os.path.join(sf(conf.log_folder), "picosat.log"), 'a') as f:
+ f.write("::" + time.strftime("%y-%m-%d-%H-%M-%S") + "::\n")
+ solut = []
+ for linen in satprc.stdout:
+ line = linen.decode(sys.getdefaultencoding())
+ f.write(line)
+ if conf.picosat_output:
+ print(line, end="")
+ if line[0] == 's':
+ if line.rstrip() == 's SATISFIABLE':
+ try:
+ solut.remove(0)
+ with open(sf(conf.config_map_file), 'a') as fm:
+ fm.write(str(utils.hash_config(solut)) + ':')
+ for sl in solut:
+ fm.write(str(sl) + ' ')
+ fm.write('\n')
+ with open(sf(conf.solved_file), 'a') as fs:
+ for sl in solut:
+ fs.write(str(-1 * sl) + ' ')
+ fs.write('\n')
+ except ValueError:
+ pass
+ solut = []
+ else:
+ os.remove(w_file.name)
+ raise exceptions.NoSolution()
+ elif line[0] == 'v':
+ for sl in line[2:].split():
+ solut.append(int(sl))
os.remove(w_file.name)
def apply():
"""Apply generated solution to kernel source.
"""
- # Check if solution_file exist
- if not os.path.isfile(sf(conf.solution_file)):
- raise Exception("Solution file is missing. Run sat_solution and check existence of " + sf(conf.solution_file))
-
utils.build_symbol_map() # Ensure smap existence
- # Read solution if satisfiable
- solut = []
- with open(sf(conf.solution_file), 'r') as f:
- if not f.readline().rstrip() == 's SATISFIABLE':
- raise NoSolution()
- for line in f:
- if line[0] == 'v':
- solut += line[2:].split()
- solut.remove('0') # Remove 0 at the end
-
- # Write solution to output_confs file
- with open(sf(conf.output_confs), 'a') as f:
- iteration = 0
- with open(sf(conf.iteration_file)) as ff:
- iteration = int(ff.readline())
- f.write(str(iteration) + ':')
- for txt in solut:
- f.write(txt + ' ')
- f.write('\n')
-
- # Write negotation solution to solver_file
- with open(sf(conf.solved_file), 'a') as f:
- for txt in solut:
- if txt[0] == '-':
- ntx = ""
- txt = txt[1:]
- else:
- ntx = "-"
- f.write( ntx + txt + " ")
- f.write("\n")
+ solved = set()
+ solution = []
+ if os.path.isfile(sf(config_solved_file)):
+ with open(sf(conf.config_solved_file)) as f:
+ for ln in f:
+ solved.add(ln.strip())
+
+ with open(sf(conf.config_map_file)) as f:
+ while True:
+ w = f.readline().split(sep=':')
+ if not w[0] in solved:
+ solution = utils.config_strtoint(w[1])
+ break;
+ if not solution:
+ raise exceptions.NoApplicableSolution()
# Load variable count
with open(sf(conf.symbol_map_file)) as f:
@@ -108,18 +122,18 @@ def apply():
var_num += 1
# Write solution to .config file in linux source folder
with open(sf(conf.linux_dot_config), 'w') as f:
- for txt in solut:
- if txt[0] == '-':
+ for s in solution:
+ if s < 0:
nt = True
- txt = txt[1:]
+ s *= -1
else:
nt = False
- if int(txt) >= var_num:
+ if s >= var_num:
break;
- if 'NONAMEGEN' in utils.smap[txt]: # ignore generated names
+ if 'NONAMEGEN' in utils.smap[s]: # ignore generated names
continue
- f.write('CONFIG_' + utils.smap[txt] + '=')
+ f.write('CONFIG_' + utils.smap[s] + '=')
if not nt:
f.write('y')
else: