]>
git.cameronkatri.com Git - apple_cmds.git/blob - file_cmds/mtree/fix_failure_locations.py
4 # This script is used to automatically fix up the location numbers in
5 # calls to RECORD_FAILURE(). When adding a new call to RECORD_FAILURE,
7 # RECORD_FAILURE(0, ...);
8 # Don't put any white space between the open parenthesis, zero and comma.
9 # Once you have added the new calls to RECORD_FAILURE, then run this script,
10 # passing it the path to the directory, like this:
11 # python3 mtree/fix_failure_locations.py mtree/
13 # This script will edit the files, changing the "0" to the next available
14 # location number. It will also detect and complain if you have duplicate
17 # DO NOT reuse location numbers! It is best if locations are consistent across
18 # all versions that have that RECORD_FAILURE call.
24 from collections
import defaultdict
25 from datetime
import datetime
,timezone
27 class LocationUpdater(object):
28 epoch
= datetime(2020, 6, 17, 23, 22, 46, 562458, tzinfo
=timezone
.utc
)
29 location_base
= int((datetime
.now(timezone
.utc
) - epoch
).total_seconds() / 60)
30 # Match the number in "RECORD_FAILURE(<number>,"
31 fail_re
= (re
.compile('(?<=\\bRECORD_FAILURE\\()\\d+(?=,)'),re
.compile('(?<=\\bRECORD_FAILURE_MSG\\()\\d+(?=,)'))
33 def __init__(self
, path
):
34 self
.location
= self
.location_base
36 # Counters for how often each location number was found
37 self
.counts
= defaultdict(int)
38 self
.locations_changed
= 0
40 # Replace the "0" in "RECORD_FAILURE(0," with next location number, in *.c
41 def fixLocations(self
):
42 def replace_loc(match
):
43 location
= int(match
.group(0))
45 # Replace location 0 with the next available location
47 self
.locations_changed
+= 1
48 location
= self
.location
49 # Count the number of times this location number was used
50 self
.counts
[location
] += 1
51 # Return the (possibly updated) location number
54 for dirpath
, dirnames
, filenames
in os
.walk(rootpath
):
55 for filename
in filenames
:
56 if filename
.endswith(".c") or filename
.endswith(".cpp"):
57 path
= os
.path
.join(dirpath
, filename
)
58 content
= open(path
, "r").read()
59 for fail_re
in self
.fail_re
:
60 if fail_re
.search(content
):
61 locations_changed_before
= self
.locations_changed
62 content
= fail_re
.sub(replace_loc
, content
)
63 if self
.locations_changed
!= locations_changed_before
:
64 # We updated a location number, so write the changed file
65 print("Updating file {}".format(path
))
66 open(path
,"w").write(content
)
69 # Return the list of keys whose count is greater than 1
70 return [k
for (k
,v
) in iter(self
.counts
.items()) if v
> 1]
72 updater
= LocationUpdater(sys
.argv
[1])
73 updater
.fixLocations()
74 dups
= updater
.duplicates()
76 print("WARNING! Duplicate location numbers: {}".format(dups
))