diff options
Diffstat (limited to 'tools/buildman/board.py')
-rw-r--r-- | tools/buildman/board.py | 144 |
1 files changed, 127 insertions, 17 deletions
diff --git a/tools/buildman/board.py b/tools/buildman/board.py index 7bcc932..a333287 100644 --- a/tools/buildman/board.py +++ b/tools/buildman/board.py @@ -5,6 +5,72 @@ import re +class Expr: + """A single regular expression for matching boards to build""" + + def __init__(self, expr): + """Set up a new Expr object. + + Args: + expr: String cotaining regular expression to store + """ + self._expr = expr + self._re = re.compile(expr) + + def Matches(self, props): + """Check if any of the properties match the regular expression. + + Args: + props: List of properties to check + Returns: + True if any of the properties match the regular expression + """ + for prop in props: + if self._re.match(prop): + return True + return False + + def __str__(self): + return self._expr + +class Term: + """A list of expressions each of which must match with properties. + + This provides a list of 'AND' expressions, meaning that each must + match the board properties for that board to be built. + """ + def __init__(self): + self._expr_list = [] + self._board_count = 0 + + def AddExpr(self, expr): + """Add an Expr object to the list to check. + + Args: + expr: New Expr object to add to the list of those that must + match for a board to be built. + """ + self._expr_list.append(Expr(expr)) + + def __str__(self): + """Return some sort of useful string describing the term""" + return '&'.join([str(expr) for expr in self._expr_list]) + + def Matches(self, props): + """Check if any of the properties match this term + + Each of the expressions in the term is checked. All must match. + + Args: + props: List of properties to check + Returns: + True if all of the expressions in the Term match, else False + """ + for expr in self._expr_list: + if not expr.Matches(props): + return False + return True + class Board: """A particular board that we can build""" def __init__(self, status, arch, cpu, soc, vendor, board_name, target, options): @@ -124,6 +190,55 @@ class Boards: """ return [board.target for board in self._boards if board.build_it] + def _BuildTerms(self, args): + """Convert command line arguments to a list of terms. + + This deals with parsing of the arguments. It handles the '&' + operator, which joins several expressions into a single Term. + + For example: + ['arm & freescale sandbox', 'tegra'] + + will produce 3 Terms containing expressions as follows: + arm, freescale + sandbox + tegra + + The first Term has two expressions, both of which must match for + a board to be selected. + + Args: + args: List of command line arguments + Returns: + A list of Term objects + """ + syms = [] + for arg in args: + for word in arg.split(): + sym_build = [] + for term in word.split('&'): + if term: + sym_build.append(term) + sym_build.append('&') + syms += sym_build[:-1] + terms = [] + term = None + oper = None + for sym in syms: + if sym == '&': + oper = sym + elif oper: + term.AddExpr(sym) + oper = None + else: + if term: + terms.append(term) + term = Term() + term.AddExpr(sym) + if term: + terms.append(term) + return terms + def SelectBoards(self, args): """Mark boards selected based on args @@ -137,26 +252,21 @@ class Boards: due to each argument, arranged by argument. """ result = {} - argres = {} - for arg in args: - result[arg] = 0 - argres[arg] = re.compile(arg) + terms = self._BuildTerms(args) + result['all'] = 0 + for term in terms: + result[str(term)] = 0 for board in self._boards: - if args: - for arg in args: - argre = argres[arg] - match = False - for prop in board.props: - match = argre.match(prop) - if match: - break - if match: - if not board.build_it: - board.build_it = True - result[arg] += 1 - result['all'] += 1 + if terms: + match = False + for term in terms: + if term.Matches(board.props): + board.build_it = True + result[str(term)] += 1 + result['all'] += 1 + break else: board.build_it = True result['all'] += 1 |