/usr/lib/python2.7/dist-packages/vamos/model.py is in undertaker 1.6.1-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 | """vamos - common auxiliary model related functionality"""
# Copyright (C) 2011-2012 Christian Dietrich <christian.dietrich@informatik.uni-erlangen.de>
# Copyright (C) 2011-2012 Reinhard Tartler <tartler@informatik.uni-erlangen.de>
# Copyright (C) 2014 Stefan Hengelein <stefan.hengelein@fau.de>
# Copyright (C) 2014 Andreas Ruprecht <rupran@einserver.de>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from vamos.rsf2model.RsfReader import ItemRsfReader, RsfReader
import logging
import re
import os
def get_model_for_arch(arch):
"""
Returns an cnf or rsf model for the given architecture
Return 'None' if no model is found.
"""
for p in ("models/%s.cnf", "models/%s.model"):
if os.path.exists(p % arch):
return p % arch
return None
def parse_model(path, shallow=False):
if path.endswith('.cnf'):
return CnfModel(path)
return RsfModel(path, shallow=shallow)
class RsfModel(dict):
def __init__(self, path, rsf=None, readrsf=True, shallow=False):
dict.__init__(self)
self.path = path
self.always_on_items = set()
self.always_off_items = set()
with open(path) as fd:
self.parse(fd)
if not rsf and path.endswith(".model"):
rsf = path[:-len(".model")] + ".rsf"
if readrsf and rsf:
try:
with open(rsf) as f:
if shallow:
self.rsf = ItemRsfReader(f)
else:
self.rsf = RsfReader(f)
except IOError:
logging.warning("no rsf file for model %s was found", path)
def parse(self, fd):
for line in fd.readlines():
line = line.strip()
if line.startswith("UNDERTAKER_SET ALWAYS_ON"):
line = line.split(" ")[2:]
always_on_items = [l.strip(" \t\"") for l in line]
for item in always_on_items:
self[item] = None
self.always_on_items.add(item)
elif line.startswith("UNDERTAKER_SET ALWAYS_OFF"):
line = line.split(" ")[2:]
always_off_items = [l.strip(" \t\"") for l in line]
for item in always_off_items:
self[item] = None
self.always_off_items.add(item)
elif line.startswith("I:") or line.startswith("UNDERTAKER_SET"):
pass
else:
line = line.split(" ", 1)
if len(line) == 1:
self[line[0]] = None
elif len(line) == 2:
self[line[0]] = line[1].strip(" \"\t\n")
def mentioned_items(self, key):
"""
@return list of mentioned items of the key's implications
"""
expr = self.get(key, "")
if expr == None:
return []
expr = re.split("[()&!|><-]", expr)
expr = [x.strip() for x in expr]
return [x for x in expr if len(x) > 0]
def leaf_features(self):
"""
Leaf features are feature that aren't mentioned anywhere else
@return list of leaf features in model
"""
# Dictionary of mentioned items
features = dict([(key, False) for key in self.keys()
if not key.endswith("_MODULE")])
for key in features.keys():
items = self.mentioned_items(key)
items += self.mentioned_items(key + "_MODULE")
for mentioned in items:
# Strip _MODULE POSTFIX
if mentioned.endswith("_MODULE"):
mentioned = mentioned[:-len("_MODULE")]
# A Leaf can't "unleaf" itself. This is important for
# circular relations like:
#
# CONFIG_A -> !CONFIG_A_MODULE
# CONFIG_A_MODULE -> !CONFIG_A
if key != mentioned and mentioned in features:
features[mentioned] = True
return sorted([key for key in features if features[key] == False])
def get_type(self, symbol):
"""
RuntimeError gets raised if no corresponding rsf is found.
@return data type of symbol.
"""
if not self.rsf:
raise RuntimeError("No corresponding rsf file found.")
if symbol.startswith("CONFIG_"):
symbol = symbol[len("CONFIG_"):]
return self.rsf.get_type(symbol)
def is_bool_tristate(self, symbol):
"""
Returns true if symbol is bool or tristate, otherwise false is returned.
Raises RuntimeError if no corresponding rsf-file is found.
"""
if not self.rsf:
raise RuntimeError("No corresponding rsf file found.")
if symbol.startswith("CONFIG_"):
symbol = symbol[len("CONFIG_"):]
return self.rsf.is_bool_tristate(symbol)
def slice_symbols(self, initial):
"""
Apply the slicing algorithm to the given set of symbols
returns a list of interesting symbol
"""
if type(initial) == list:
stack = initial
else:
stack = [initial]
visited = set()
while len(stack) > 0:
symbol = stack.pop()
visited.add(symbol)
for new_symbols in self.mentioned_items(symbol):
if not new_symbols in visited:
stack.append(new_symbols)
return list(visited)
def is_defined(self, feature):
"""
Return true if feature is defined in the model.
"""
return feature in self.keys()
class CnfModel(dict):
def __init__(self, path):
dict.__init__(self)
self.path = path
self.always_on_items = set()
self.always_off_items = set()
self.symbols = {}
with open(path) as fd:
self.parse(fd)
def parse(self, fd):
sym_regexp = re.compile(r"^c sym (.+) (\d)$")
meta_regexp = re.compile(r"^c meta_value ([^\s]+)\s+(.+)$")
for line in fd.readlines():
m = sym_regexp.match(line)
if m:
sym = 'CONFIG_' + m.group(1)
code = int(m.group(2))
self[sym] = None
self.symbols[sym] = code
# tristate symbols also have a _MODULE sister
if code == 2:
self[sym + '_MODULE'] = None
self[sym + '_MODULE'] = code
continue
m = meta_regexp.match(line)
if m:
if m.group(1) == 'ALWAYS_ON':
self.always_on_items.add(m.group(2))
if m.group(1) == 'ALWAYS_OFF':
self.always_off_items.add(m.group(2))
def get_type(self, symbol):
"""
@raises RuntimeError if no corresponding rsf is found.
@return data type of symbol.
"""
if not symbol.startswith("CONFIG_"):
symbol = "CONFIG_" + symbol
if not symbol in self.symbols:
raise RuntimeError("Symbol %s not found" % symbol)
code = int(self.symbols[symbol])
if code == 1:
return 'boolean'
if code == 2:
return 'tristate'
if code == 3:
return 'integer'
if code == 4:
return 'hex'
if code == 5:
return 'string'
if code == 6:
return 'other'
raise RuntimeError("Unknown type code code %d" % code)
def is_bool_tristate(self, symbol):
"""
@raises RuntimeError on internal errors
@return True if symbol is tristate, otherwise False
"""
if not symbol.startswith("CONFIG_"):
symbol = "CONFIG_" + symbol
if not symbol in self.symbols:
raise RuntimeError("Symbol %s not found" % symbol)
code = self.symbols[symbol]
return code == 1 or code == 2
|