line_matcher.py 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. # Copyright 2015-2021 Espressif Systems (Shanghai) CO LTD
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License");
  4. # you may not use this file except in compliance with the License.
  5. # You may obtain a copy of the License at
  6. #
  7. # http://www.apache.org/licenses/LICENSE-2.0
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS,
  11. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. # See the License for the specific language governing permissions and
  13. # limitations under the License.
  14. import re
  15. class LineMatcher(object):
  16. """
  17. Assembles a dictionary of filtering rules based on the --print_filter
  18. argument of idf_monitor. Then later it is used to match lines and
  19. determine whether they should be shown on screen or not.
  20. """
  21. LEVEL_N = 0
  22. LEVEL_E = 1
  23. LEVEL_W = 2
  24. LEVEL_I = 3
  25. LEVEL_D = 4
  26. LEVEL_V = 5
  27. level = {'N': LEVEL_N, 'E': LEVEL_E, 'W': LEVEL_W, 'I': LEVEL_I, 'D': LEVEL_D,
  28. 'V': LEVEL_V, '*': LEVEL_V, '': LEVEL_V}
  29. def __init__(self, print_filter):
  30. # type: (str) -> None
  31. self._dict = dict()
  32. self._re = re.compile(r'^(?:\033\[[01];?[0-9]+m?)?([EWIDV]) \([0-9]+\) ([^:]+): ')
  33. items = print_filter.split()
  34. if len(items) == 0:
  35. self._dict['*'] = self.LEVEL_V # default is to print everything
  36. for f in items:
  37. s = f.split(r':')
  38. if len(s) == 1:
  39. # specifying no warning level defaults to verbose level
  40. lev = self.LEVEL_V
  41. elif len(s) == 2:
  42. if len(s[0]) == 0:
  43. raise ValueError('No tag specified in filter ' + f)
  44. try:
  45. lev = self.level[s[1].upper()]
  46. except KeyError:
  47. raise ValueError('Unknown warning level in filter ' + f)
  48. else:
  49. raise ValueError('Missing ":" in filter ' + f)
  50. self._dict[s[0]] = lev
  51. def match(self, line):
  52. # type: (str) -> bool
  53. try:
  54. m = self._re.search(line)
  55. if m:
  56. lev = self.level[m.group(1)]
  57. if m.group(2) in self._dict:
  58. return self._dict[m.group(2)] >= lev
  59. return self._dict.get('*', self.LEVEL_N) >= lev
  60. except (KeyError, IndexError):
  61. # Regular line written with something else than ESP_LOG*
  62. # or an empty line.
  63. pass
  64. # We need something more than "*.N" for printing.
  65. return self._dict.get('*', self.LEVEL_N) > self.LEVEL_N