| #!/usr/bin/env python3 |
| # -*- coding: utf-8 -*- |
| # |
| # Copyright (C) 2017-2020 The Project X-Ray Authors. |
| # |
| # Use of this source code is governed by a ISC-style |
| # license that can be found in the LICENSE file or at |
| # https://opensource.org/licenses/ISC |
| # |
| # SPDX-License-Identifier: ISC |
| |
| import os, sys, re |
| from prjxray import util |
| |
| TAG_PART_RE = re.compile(r"^[a-zA-Z][0-9a-zA-Z_]*(\[[0-9]+\])?$") |
| |
| |
| def check_tag_name(tag): |
| ''' |
| Checks if the tag name given by the used conforms to the valid fasm |
| name rules. |
| |
| >>> check_tag_name("CELL.feature19.ENABLED") |
| True |
| >>> check_tag_name("FEATURE") |
| True |
| >>> check_tag_name("TAG.") |
| False |
| >>> check_tag_name(".TAG") |
| False |
| >>> check_tag_name("CELL..FEATURE") |
| False |
| >>> check_tag_name("CELL.3ENABLE") |
| False |
| >>> check_tag_name("FEATURE.12.ON") |
| False |
| ''' |
| |
| for part in tag.split("."): |
| if not len(part) or TAG_PART_RE.match(part) is None: |
| return False |
| |
| return True |
| |
| |
| def run(fn_ins, fn_out, strict=False, track_origin=False, verbose=False): |
| # tag to bits |
| entries = {} |
| # tag to (bits, line) |
| tags = dict() |
| # bits to (tag, line) |
| bitss = dict() |
| |
| for fn_in in fn_ins: |
| for line, (tag, bits, mode, origin) in util.parse_db_lines(fn_in): |
| line = line.strip() |
| assert mode is not None or mode != "always", "strict: got ill defined line: %s" % ( |
| line, ) |
| |
| if not check_tag_name(tag): |
| assert not strict, "strict: Invalid tag name '{}'".format(tag) |
| |
| if tag in tags: |
| orig_bits, orig_line, orig_origin = tags[tag] |
| if orig_bits != bits: |
| print( |
| "WARNING: got duplicate tag %s" % (tag, ), |
| file=sys.stderr) |
| print(" Orig line: %s" % orig_line, file=sys.stderr) |
| print(" New line : %s" % line, file=sys.stderr) |
| assert not strict, "strict: got duplicate tag" |
| origin = os.path.basename(os.getcwd()) |
| if track_origin and orig_origin != origin: |
| origin = orig_origin + "," + origin |
| if bits in bitss: |
| orig_tag, orig_line = bitss[bits] |
| if orig_tag != tag: |
| print( |
| "WARNING: got duplicate bits %s" % (bits, ), |
| file=sys.stderr) |
| print(" Orig line: %s" % orig_line, file=sys.stderr) |
| print(" New line : %s" % line, file=sys.stderr) |
| assert not strict, "strict: got duplicate bits" |
| |
| if track_origin and origin is None: |
| origin = os.path.basename(os.getcwd()) |
| entries[tag] = (bits, origin) |
| tags[tag] = (bits, line, origin) |
| if bits != None: |
| bitss[bits] = (tag, line) |
| |
| util.write_db_lines(fn_out, entries, track_origin) |
| |
| |
| def main(): |
| import argparse |
| |
| parser = argparse.ArgumentParser(description="Combine multiple .db files") |
| |
| util.db_root_arg(parser) |
| parser.add_argument('--verbose', action='store_true', help='') |
| parser.add_argument('--track_origin', action='store_true', help='') |
| parser.add_argument('--out', help='') |
| parser.add_argument('ins', nargs='+', help='Last takes precedence') |
| args = parser.parse_args() |
| |
| run( |
| args.ins, |
| args.out, |
| strict=int(os.getenv("MERGEDB_STRICT", "1")), |
| track_origin=args.track_origin, |
| verbose=args.verbose) |
| |
| |
| if __name__ == '__main__': |
| main() |