1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33 from python_qt_binding.QtCore import QObject, Signal
34 from python_qt_binding.QtCore import QRegExp, QFile
35 import os
36 import rospy
37 import threading
38
39 import node_manager_fkie as nm
40
41 from .parser_functions import interpret_path
42
43
44 -class TextSearchThread(QObject, threading.Thread):
45 '''
46 A thread to search recursive for a text in files.
47 '''
48 search_result_signal = Signal(str, bool, str, int, int, str)
49 ''' @ivar: A signal emitted after search_threaded was started.
50 (search text, found or not, file, position in text, line number, line text)
51 for each result a signal will be emitted.
52 '''
53 warning_signal = Signal(str)
54
55 - def __init__(self, search_text, path, is_regex=False, path_text={}, recursive=False):
56 '''
57 :param search_text: text to search for
58 :type search_text: str
59 :param path: initial file path
60 :type path: str
61 .param is_regex: is the search_text a regular expressions
62 :type is_regex: bool
63 '''
64 QObject.__init__(self)
65 threading.Thread.__init__(self)
66 self._search_text = search_text
67 self._path = path
68 self._path_text = path_text
69 self._recursive = recursive
70 self._isrunning = True
71 self.setDaemon(True)
72
74 self._isrunning = False
75
77 '''
78 '''
79 try:
80 self.search(self._search_text, self._path, self._recursive)
81 except:
82 import traceback
83
84 formatted_lines = traceback.format_exc(1).splitlines()
85 rospy.logwarn("Error while search for '%s' in '%s': %s" % (self._search_text, self._path, formatted_lines[-1]))
86 self.warning_signal.emit(formatted_lines[-1])
87 finally:
88 if self._isrunning:
89 self.search_result_signal.emit(self._search_text, False, '', -1, -1, '')
90
91 - def search(self, search_text, path, recursive=False):
92 '''
93 Searches for given text in this document and all included files.
94 @param search_text: text to find
95 @type search_text: C{str}
96 @return: the list with all files contain the text
97 @rtype: C{[str, ...]}
98 '''
99 data = self._get_text(path)
100 pos = data.find(search_text)
101 slen = len(search_text)
102 while pos != -1 and self._isrunning:
103 if self._isrunning:
104 self.search_result_signal.emit(search_text, True, path, pos, data.count('\n', 0, pos) + 1, self._strip_text(data, pos))
105 pos += slen
106 pos = data.find(search_text, pos)
107 if self._isrunning:
108 inc_files = self._included_files(path)
109 for incf in inc_files:
110 if not self._isrunning:
111 break
112 if recursive:
113 self.search(search_text, incf)
114
115 - def _get_text(self, path):
116 if path in self._path_text:
117 return self._path_text[path]
118 with open(path, 'r') as f:
119 data = f.read()
120 return data
121 return ''
122
123 - def _included_files(self, path):
124 '''
125 Returns all included files in the given file.
126 '''
127 result = []
128 with open(path, 'r') as f:
129 data = f.read()
130 reg = QRegExp("=[\s\t]*\".*\"")
131 reg.setMinimal(True)
132 pos = reg.indexIn(data)
133 while pos != -1 and self._isrunning:
134 try:
135 pp = interpret_path(reg.cap(0).strip('"'))
136 f = QFile(pp)
137 ext = os.path.splitext(pp)
138 if f.exists() and ext[1] in nm.settings().SEARCH_IN_EXT:
139 result.append(pp)
140 except Exception as exp:
141 parsed_text = pp
142 try:
143 parsed_text = reg.cap(0).strip('"')
144 except:
145 pass
146 self.warning_signal.emit("Error while parse '%s': %s" % (parsed_text, exp))
147 pos += reg.matchedLength()
148 pos = reg.indexIn(data, pos)
149 return result
150
151 - def _strip_text(self, data, pos):
152 start = pos
153 end = pos
154 while start > 0 and data[start - 1] not in ['\n', '\0', '\r']:
155 start -= 1
156 while end < len(data) and data[end] not in ['\n', '\0', '\r']:
157 end += 1
158 return data[start:end].strip()
159