line_matcher.py 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. # SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
  2. # SPDX-License-Identifier: Apache-2.0
  3. import re
  4. class LineMatcher(object):
  5. """
  6. Assembles a dictionary of filtering rules based on the --print_filter
  7. argument of idf_monitor. Then later it is used to match lines and
  8. determine whether they should be shown on screen or not.
  9. """
  10. LEVEL_N = 0
  11. LEVEL_E = 1
  12. LEVEL_W = 2
  13. LEVEL_I = 3
  14. LEVEL_D = 4
  15. LEVEL_V = 5
  16. level = {'N': LEVEL_N, 'E': LEVEL_E, 'W': LEVEL_W, 'I': LEVEL_I, 'D': LEVEL_D,
  17. 'V': LEVEL_V, '*': LEVEL_V, '': LEVEL_V}
  18. def __init__(self, print_filter):
  19. # type: (str) -> None
  20. self._dict = dict()
  21. self._re = re.compile(r'^(?:\033\[[01];?[0-9]+m?)?([EWIDV]) \([0-9]+\) ([^:]+): ')
  22. items = print_filter.split()
  23. if len(items) == 0:
  24. self._dict['*'] = self.LEVEL_V # default is to print everything
  25. for f in items:
  26. s = f.split(r':')
  27. if len(s) == 1:
  28. # specifying no warning level defaults to verbose level
  29. lev = self.LEVEL_V
  30. elif len(s) == 2:
  31. if len(s[0]) == 0:
  32. raise ValueError('No tag specified in filter ' + f)
  33. try:
  34. lev = self.level[s[1].upper()]
  35. except KeyError:
  36. raise ValueError('Unknown warning level in filter ' + f)
  37. else:
  38. raise ValueError('Missing ":" in filter ' + f)
  39. self._dict[s[0]] = lev
  40. def match(self, line):
  41. # type: (str) -> bool
  42. try:
  43. m = self._re.search(line)
  44. if m:
  45. lev = self.level[m.group(1)]
  46. if m.group(2) in self._dict:
  47. return self._dict[m.group(2)] >= lev
  48. return self._dict.get('*', self.LEVEL_N) >= lev
  49. except (KeyError, IndexError):
  50. # Regular line written with something else than ESP_LOG*
  51. # or an empty line.
  52. pass
  53. # We need something more than "*.N" for printing.
  54. return self._dict.get('*', self.LEVEL_N) > self.LEVEL_N