Skip to content

Commit e4874a6

Browse files
Add time limited matching.
1 parent 076e435 commit e4874a6

4 files changed

Lines changed: 69 additions & 17 deletions

File tree

README.md

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,33 @@ supported.
1717
Install **ReSearch** by clicking "Install" on the **Re Search** entry in the
1818
Extensions panel.
1919

20-
Use the Analyzers side panel to use a Re Search analyzer with a suitable low
21-
level analyser. At present the Async Serial analyzer is well supported. I2C
22-
partial support has been added, but not thoroughly tested. Untested support for
23-
other LLAs may be added in the future.
24-
25-
In the ReSearch Settings dialog select the required input analyzer then set the
26-
regular expression match string. Python regular expression syntax is used for
27-
the match string. Note that the provided match is not checked for syntax errors
28-
(a badly formed string will generate a somewhat cryptic error dialog in Logic!)
20+
Use the Analyzers side panel to add a Re Search analyzer.
21+
22+
In the ReSearch Settings dialog select the LLA. At present the Async Serial
23+
analyzer is well supported. I2C partial support has been added, but is not
24+
thoroughly tested. Support for other LLAs may be added in the future.
25+
26+
### Match
27+
28+
Use the Match setting to set teh regular expression. Python regular expression
29+
syntax is used for the match string. Note that the provided match is not checked
30+
for syntax errors (a badly formed string will generate a somewhat cryptic error
31+
dialog in Logic!).
32+
33+
Note that trailing wild card matches are generally not useful as the match is
34+
performed when each character is added to the target string. For example, `fox.*`
35+
will match `fox`, at which point all characters up to and including `fox` will
36+
be dropped. Anchor the end of the expression with a non-wild pattern. Often a
37+
positive look ahead match (`(?= ...)`) is useful as an anchor.
38+
39+
### Max span (s)
40+
41+
Use the **Max span (s)** setting to specify the maximum width in seconds allowed
42+
for a match. This can be used to match only within a block of text when there is
43+
significant time between blocks for example. It also makes the matching process
44+
run faster because it can ignore anything that is too old.
45+
46+
Setting **Max span (s)** to `0` or leaving it blank turns this feature off.
2947

3048
## Data Rendering
3149

ReSearch.png

7.85 KB
Loading

ReSearch.py

Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import re
22
from datetime import datetime
3-
from saleae.analyzers import HighLevelAnalyzer, AnalyzerFrame, StringSetting
3+
from saleae.analyzers import HighLevelAnalyzer, AnalyzerFrame
4+
from saleae.analyzers import NumberSetting, StringSetting
45
from saleae.data import GraphTimeDelta as GTD
56

67
kTimeZero = datetime(1, 1, 1)
@@ -73,11 +74,37 @@ def Drop(self, lastIndex):
7374
# the string. Trim the string and update the block start time
7475
startEpoch = block.start
7576
endEpoch = block.end
76-
charTime = (endEpoch - startEpoch) / strLen
7777
delChars = lastIndex - blockStartIndex
78-
block.start = startEpoch + GTD(charTime * delChars)
78+
block.start = startEpoch + GTD(block.charTime * delChars)
7979
block.str = block.str[lastIndex - blockStartIndex : ]
80-
block.charTime = charTime
80+
return
81+
82+
def DropBefore(self, timeDelta):
83+
# Remove all blocks before the end time of the last block - timeDelta
84+
if not len(self.blocks):
85+
return
86+
87+
# Calculate the cut off time
88+
cutOffTime = self.blocks[-1].end - GTD(timeDelta)
89+
90+
while len(self.blocks):
91+
block = self.blocks[0]
92+
strLen = len(block.str)
93+
94+
if block.start > cutOffTime:
95+
# Whole block is within allowed time span. Done
96+
return
97+
98+
if block.end < cutOffTime:
99+
# None of the block is within the allowed time span. Drop it.
100+
del self.blocks[0]
101+
continue
102+
103+
# The block spans the start of the allowed time span. Trim the
104+
# block.
105+
delCount = int((float(cutOffTime - block.start) + block.charTime) / block.charTime)
106+
block.start += GTD(delCount * block.charTime)
107+
block.str = block.str[delCount : ]
81108
return
82109

83110
def Match(self, drop = False):
@@ -142,6 +169,7 @@ def Match(self, drop = False):
142169
class ReSearch(HighLevelAnalyzer):
143170

144171
kMatch = StringSetting(label = "Match")
172+
kMatchTime = StringSetting(label = "Max span (s)")
145173

146174
result_types = {
147175
"Matched": {"format": "{{{data.Matched}}}"},
@@ -188,9 +216,7 @@ def AddData(self, params):
188216
if 'address' in params.data and params.data["address"]:
189217
asStr = '@' + hex(params.data["data"][0]) + ' '
190218

191-
elif self.haveAddress \
192-
or params.data["data"][0] > 127 \
193-
or params.data["data"][0] < 32:
219+
elif self.haveAddress or params.data["data"][0] > 127:
194220
# I2C or other bus protocol with addressed devices or the character
195221
# from an async serial analyzer is outside the ASCII range
196222
asStr = hex(params.data["data"][0]) + ' '
@@ -218,6 +244,11 @@ def __init__(self):
218244
self.isSource = False
219245
self.Reset()
220246

247+
if not len(self.kMatchTime):
248+
self.kMatchTime = "0"
249+
250+
self.kMatchTime = float(str(self.kMatchTime))
251+
221252
# handlers return True if a match should be attempted
222253
self.handlerDispatch = {
223254
"address": self.AddAddress,
@@ -238,6 +269,9 @@ def decode(self, newFrame: AnalyzerFrame):
238269
if not self.handlerDispatch[newFrame.type](newFrame):
239270
return
240271

272+
if self.kMatchTime:
273+
self.blocks.DropBefore(self.kMatchTime)
274+
241275
match = self.blocks.Match(drop = True)
242276

243277
if not match:

extension.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"version": "1.2",
2+
"version": "1.3",
33
"apiVersion": "1.0.0",
44
"author": "Peter Jaquiery",
55
"description": "Match text in async serial logging",

0 commit comments

Comments
 (0)