From 5fd83771641d15c418f747bd343ba6738d3875f7 Mon Sep 17 00:00:00 2001 From: Cameron Katri Date: Sun, 9 May 2021 14:20:58 -0400 Subject: Import macOS userland adv_cmds-176 basic_cmds-55 bootstrap_cmds-116.100.1 developer_cmds-66 diskdev_cmds-667.40.1 doc_cmds-53.60.1 file_cmds-321.40.3 mail_cmds-35 misc_cmds-34 network_cmds-606.40.1 patch_cmds-17 remote_cmds-63 shell_cmds-216.60.1 system_cmds-880.60.2 text_cmds-106 --- file_cmds/mtree/fix_failure_locations.py | 77 ++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100755 file_cmds/mtree/fix_failure_locations.py (limited to 'file_cmds/mtree/fix_failure_locations.py') diff --git a/file_cmds/mtree/fix_failure_locations.py b/file_cmds/mtree/fix_failure_locations.py new file mode 100755 index 0000000..a49906e --- /dev/null +++ b/file_cmds/mtree/fix_failure_locations.py @@ -0,0 +1,77 @@ +#!/usr/bin/python + +# +# This script is used to automatically fix up the location numbers in +# calls to RECORD_FAILURE(). When adding a new call to RECORD_FAILURE, +# write it like: +# RECORD_FAILURE(0, ...); +# Don't put any white space between the open parenthesis, zero and comma. +# Once you have added the new calls to RECORD_FAILURE, then run this script, +# passing it the path to the directory, like this: +# python3 mtree/fix_failure_locations.py mtree/ +# +# This script will edit the files, changing the "0" to the next available +# location number. It will also detect and complain if you have duplicate +# location numbers. +# +# DO NOT reuse location numbers! It is best if locations are consistent across +# all versions that have that RECORD_FAILURE call. +# + +import sys +import os +import re +from collections import defaultdict +from datetime import datetime,timezone + +class LocationUpdater(object): + epoch = datetime(2020, 6, 17, 23, 22, 46, 562458, tzinfo=timezone.utc) + location_base = int((datetime.now(timezone.utc) - epoch).total_seconds() / 60) + # Match the number in "RECORD_FAILURE(," + fail_re = (re.compile('(?<=\\bRECORD_FAILURE\\()\\d+(?=,)'),re.compile('(?<=\\bRECORD_FAILURE_MSG\\()\\d+(?=,)')) + + def __init__(self, path): + self.location = self.location_base + self.path = path + # Counters for how often each location number was found + self.counts = defaultdict(int) + self.locations_changed = 0 + + # Replace the "0" in "RECORD_FAILURE(0," with next location number, in *.c + def fixLocations(self): + def replace_loc(match): + location = int(match.group(0)) + if location == 0: + # Replace location 0 with the next available location + self.location += 1 + self.locations_changed += 1 + location = self.location + # Count the number of times this location number was used + self.counts[location] += 1 + # Return the (possibly updated) location number + return str(location) + rootpath = self.path + for dirpath, dirnames, filenames in os.walk(rootpath): + for filename in filenames: + if filename.endswith(".c") or filename.endswith(".cpp"): + path = os.path.join(dirpath, filename) + content = open(path, "r").read() + for fail_re in self.fail_re: + if fail_re.search(content): + locations_changed_before = self.locations_changed + content = fail_re.sub(replace_loc, content) + if self.locations_changed != locations_changed_before: + # We updated a location number, so write the changed file + print("Updating file {}".format(path)) + open(path,"w").write(content) + + def duplicates(self): + # Return the list of keys whose count is greater than 1 + return [k for (k,v) in iter(self.counts.items()) if v > 1] + +updater = LocationUpdater(sys.argv[1]) +updater.fixLocations() +dups = updater.duplicates() +if len(dups): + print("WARNING! Duplicate location numbers: {}".format(dups)) + sys.exit(1) -- cgit v1.2.3