1c9af18a5SGreg Clayton //===-- CommandCompletions.cpp ----------------------------------*- C++ -*-===//
2c9af18a5SGreg Clayton //
3c9af18a5SGreg Clayton //                     The LLVM Compiler Infrastructure
4c9af18a5SGreg Clayton //
5c9af18a5SGreg Clayton // This file is distributed under the University of Illinois Open Source
6c9af18a5SGreg Clayton // License. See LICENSE.TXT for details.
7c9af18a5SGreg Clayton //
8c9af18a5SGreg Clayton //===----------------------------------------------------------------------===//
9c9af18a5SGreg Clayton 
10c9af18a5SGreg Clayton 
11c9af18a5SGreg Clayton // C Includes
12c9af18a5SGreg Clayton // C++ Includes
13c9af18a5SGreg Clayton // Other libraries and framework includes
14c9af18a5SGreg Clayton // Project includes
15*40af72e1SJim Ingham #include "lldb/Interpreter/Args.h"
16c9af18a5SGreg Clayton #include "lldb/Interpreter/CommandInterpreter.h"
17c9af18a5SGreg Clayton #include "lldb/Core/FileSpecList.h"
18c9af18a5SGreg Clayton #include "lldb/Target/Target.h"
19c9af18a5SGreg Clayton #include "lldb/Interpreter/CommandCompletions.h"
20c9af18a5SGreg Clayton 
21c9af18a5SGreg Clayton 
22c9af18a5SGreg Clayton using namespace lldb_private;
23c9af18a5SGreg Clayton 
24c9af18a5SGreg Clayton CommandCompletions::CommonCompletionElement
25c9af18a5SGreg Clayton CommandCompletions::g_common_completions[] =
26c9af18a5SGreg Clayton {
27c9af18a5SGreg Clayton     {eCustomCompletion,     NULL},
28c9af18a5SGreg Clayton     {eSourceFileCompletion, CommandCompletions::SourceFiles},
29c9af18a5SGreg Clayton     {eDiskFileCompletion,   NULL},
30c9af18a5SGreg Clayton     {eSymbolCompletion,     CommandCompletions::Symbols},
31c9af18a5SGreg Clayton     {eModuleCompletion,     CommandCompletions::Modules},
32c9af18a5SGreg Clayton     {eNoCompletion,         NULL}      // This one has to be last in the list.
33c9af18a5SGreg Clayton };
34c9af18a5SGreg Clayton 
35c9af18a5SGreg Clayton bool
36c9af18a5SGreg Clayton CommandCompletions::InvokeCommonCompletionCallbacks (uint32_t completion_mask,
37c9af18a5SGreg Clayton                                                 const char *completion_str,
38c9af18a5SGreg Clayton                                                 int match_start_point,
39c9af18a5SGreg Clayton                                                 int max_return_elements,
40c9af18a5SGreg Clayton                                                 lldb_private::CommandInterpreter *interpreter,
41c9af18a5SGreg Clayton                                                 SearchFilter *searcher,
42c9af18a5SGreg Clayton                                                 lldb_private::StringList &matches)
43c9af18a5SGreg Clayton {
44c9af18a5SGreg Clayton     bool handled = false;
45c9af18a5SGreg Clayton 
46c9af18a5SGreg Clayton     if (completion_mask & eCustomCompletion)
47c9af18a5SGreg Clayton         return false;
48c9af18a5SGreg Clayton 
49c9af18a5SGreg Clayton     for (int i = 0; ; i++)
50c9af18a5SGreg Clayton     {
51c9af18a5SGreg Clayton         if (g_common_completions[i].type == eNoCompletion)
52c9af18a5SGreg Clayton             break;
53c9af18a5SGreg Clayton          else if ((g_common_completions[i].type & completion_mask) == g_common_completions[i].type
54c9af18a5SGreg Clayton                    && g_common_completions[i].callback != NULL)
55c9af18a5SGreg Clayton          {
56c9af18a5SGreg Clayton             handled = true;
57c9af18a5SGreg Clayton             g_common_completions[i].callback (completion_str,
58c9af18a5SGreg Clayton                                               match_start_point,
59c9af18a5SGreg Clayton                                               max_return_elements,
60c9af18a5SGreg Clayton                                               interpreter,
61c9af18a5SGreg Clayton                                               searcher,
62c9af18a5SGreg Clayton                                               matches);
63c9af18a5SGreg Clayton         }
64c9af18a5SGreg Clayton     }
65c9af18a5SGreg Clayton     return handled;
66c9af18a5SGreg Clayton }
67c9af18a5SGreg Clayton 
68c9af18a5SGreg Clayton int
69c9af18a5SGreg Clayton CommandCompletions::SourceFiles (const char *partial_file_name,
70c9af18a5SGreg Clayton                     int match_start_point,
71c9af18a5SGreg Clayton                     int max_return_elements,
72c9af18a5SGreg Clayton                     lldb_private::CommandInterpreter *interpreter,
73c9af18a5SGreg Clayton                     SearchFilter *searcher,
74c9af18a5SGreg Clayton                     lldb_private::StringList &matches)
75c9af18a5SGreg Clayton {
76c9af18a5SGreg Clayton     // Find some way to switch "include support files..."
77c9af18a5SGreg Clayton     SourceFileCompleter completer (false, partial_file_name, match_start_point, max_return_elements, interpreter,
78c9af18a5SGreg Clayton                                    matches);
79c9af18a5SGreg Clayton 
80c9af18a5SGreg Clayton     if (searcher == NULL)
81c9af18a5SGreg Clayton     {
82c9af18a5SGreg Clayton         lldb::TargetSP target_sp = interpreter->Context()->GetTarget()->GetSP();
83c9af18a5SGreg Clayton         SearchFilter null_searcher (target_sp);
84c9af18a5SGreg Clayton         completer.DoCompletion (&null_searcher);
85c9af18a5SGreg Clayton     }
86c9af18a5SGreg Clayton     else
87c9af18a5SGreg Clayton     {
88c9af18a5SGreg Clayton         completer.DoCompletion (searcher);
89c9af18a5SGreg Clayton     }
90c9af18a5SGreg Clayton     return matches.GetSize();
91c9af18a5SGreg Clayton }
92c9af18a5SGreg Clayton 
93c9af18a5SGreg Clayton int
94c9af18a5SGreg Clayton CommandCompletions::Modules (const char *partial_file_name,
95c9af18a5SGreg Clayton                     int match_start_point,
96c9af18a5SGreg Clayton                     int max_return_elements,
97c9af18a5SGreg Clayton                     lldb_private::CommandInterpreter *interpreter,
98c9af18a5SGreg Clayton                     SearchFilter *searcher,
99c9af18a5SGreg Clayton                     lldb_private::StringList &matches)
100c9af18a5SGreg Clayton {
101c9af18a5SGreg Clayton     ModuleCompleter completer(partial_file_name, match_start_point, max_return_elements, interpreter, matches);
102c9af18a5SGreg Clayton 
103c9af18a5SGreg Clayton     if (searcher == NULL)
104c9af18a5SGreg Clayton     {
105c9af18a5SGreg Clayton         lldb::TargetSP target_sp = interpreter->Context()->GetTarget()->GetSP();
106c9af18a5SGreg Clayton         SearchFilter null_searcher (target_sp);
107c9af18a5SGreg Clayton         completer.DoCompletion (&null_searcher);
108c9af18a5SGreg Clayton     }
109c9af18a5SGreg Clayton     else
110c9af18a5SGreg Clayton     {
111c9af18a5SGreg Clayton         completer.DoCompletion (searcher);
112c9af18a5SGreg Clayton     }
113c9af18a5SGreg Clayton     return matches.GetSize();
114c9af18a5SGreg Clayton }
115c9af18a5SGreg Clayton 
116c9af18a5SGreg Clayton int
117c9af18a5SGreg Clayton CommandCompletions::Symbols (const char *partial_file_name,
118c9af18a5SGreg Clayton                     int match_start_point,
119c9af18a5SGreg Clayton                     int max_return_elements,
120c9af18a5SGreg Clayton                     lldb_private::CommandInterpreter *interpreter,
121c9af18a5SGreg Clayton                     SearchFilter *searcher,
122c9af18a5SGreg Clayton                     lldb_private::StringList &matches)
123c9af18a5SGreg Clayton {
124c9af18a5SGreg Clayton     SymbolCompleter completer(partial_file_name, match_start_point, max_return_elements, interpreter, matches);
125c9af18a5SGreg Clayton 
126c9af18a5SGreg Clayton     if (searcher == NULL)
127c9af18a5SGreg Clayton     {
128c9af18a5SGreg Clayton         lldb::TargetSP target_sp = interpreter->Context()->GetTarget()->GetSP();
129c9af18a5SGreg Clayton         SearchFilter null_searcher (target_sp);
130c9af18a5SGreg Clayton         completer.DoCompletion (&null_searcher);
131c9af18a5SGreg Clayton     }
132c9af18a5SGreg Clayton     else
133c9af18a5SGreg Clayton     {
134c9af18a5SGreg Clayton         completer.DoCompletion (searcher);
135c9af18a5SGreg Clayton     }
136c9af18a5SGreg Clayton     return matches.GetSize();
137c9af18a5SGreg Clayton }
138c9af18a5SGreg Clayton 
139c9af18a5SGreg Clayton CommandCompletions::Completer::Completer (
140c9af18a5SGreg Clayton     const char *completion_str,
141c9af18a5SGreg Clayton     int match_start_point,
142c9af18a5SGreg Clayton     int max_return_elements,
143c9af18a5SGreg Clayton     CommandInterpreter *interpreter,
144c9af18a5SGreg Clayton     StringList &matches
145c9af18a5SGreg Clayton ) :
146c9af18a5SGreg Clayton     m_completion_str (completion_str),
147c9af18a5SGreg Clayton     m_match_start_point (match_start_point),
148c9af18a5SGreg Clayton     m_max_return_elements (max_return_elements),
149c9af18a5SGreg Clayton     m_interpreter (interpreter),
150c9af18a5SGreg Clayton     m_matches (matches)
151c9af18a5SGreg Clayton {
152c9af18a5SGreg Clayton }
153c9af18a5SGreg Clayton 
154c9af18a5SGreg Clayton CommandCompletions::Completer::~Completer ()
155c9af18a5SGreg Clayton {
156c9af18a5SGreg Clayton 
157c9af18a5SGreg Clayton }
158c9af18a5SGreg Clayton 
159c9af18a5SGreg Clayton //----------------------------------------------------------------------
160c9af18a5SGreg Clayton // SourceFileCompleter
161c9af18a5SGreg Clayton //----------------------------------------------------------------------
162c9af18a5SGreg Clayton 
163c9af18a5SGreg Clayton CommandCompletions::SourceFileCompleter::SourceFileCompleter (
164c9af18a5SGreg Clayton     bool include_support_files,
165c9af18a5SGreg Clayton     const char *completion_str,
166c9af18a5SGreg Clayton     int match_start_point,
167c9af18a5SGreg Clayton     int max_return_elements,
168c9af18a5SGreg Clayton     CommandInterpreter *interpreter,
169c9af18a5SGreg Clayton     StringList &matches
170c9af18a5SGreg Clayton ) :
171c9af18a5SGreg Clayton     CommandCompletions::Completer (completion_str, match_start_point, max_return_elements, interpreter, matches),
172c9af18a5SGreg Clayton     m_include_support_files (include_support_files),
173c9af18a5SGreg Clayton     m_matching_files()
174c9af18a5SGreg Clayton {
175c9af18a5SGreg Clayton     FileSpec partial_spec (m_completion_str.c_str());
176c9af18a5SGreg Clayton     m_file_name = partial_spec.GetFilename().GetCString();
177c9af18a5SGreg Clayton     m_dir_name = partial_spec.GetDirectory().GetCString();
178c9af18a5SGreg Clayton }
179c9af18a5SGreg Clayton 
180c9af18a5SGreg Clayton Searcher::Depth
181c9af18a5SGreg Clayton CommandCompletions::SourceFileCompleter::GetDepth()
182c9af18a5SGreg Clayton {
183c9af18a5SGreg Clayton     return eDepthCompUnit;
184c9af18a5SGreg Clayton }
185c9af18a5SGreg Clayton 
186c9af18a5SGreg Clayton Searcher::CallbackReturn
187c9af18a5SGreg Clayton CommandCompletions::SourceFileCompleter::SearchCallback (
188c9af18a5SGreg Clayton     SearchFilter &filter,
189c9af18a5SGreg Clayton     SymbolContext &context,
190c9af18a5SGreg Clayton     Address *addr,
191c9af18a5SGreg Clayton     bool complete
192c9af18a5SGreg Clayton )
193c9af18a5SGreg Clayton {
194c9af18a5SGreg Clayton     if (context.comp_unit != NULL)
195c9af18a5SGreg Clayton     {
196c9af18a5SGreg Clayton         if (m_include_support_files)
197c9af18a5SGreg Clayton         {
198c9af18a5SGreg Clayton             FileSpecList supporting_files = context.comp_unit->GetSupportFiles();
199c9af18a5SGreg Clayton             for (size_t sfiles = 0; sfiles < supporting_files.GetSize(); sfiles++)
200c9af18a5SGreg Clayton             {
201c9af18a5SGreg Clayton                 const FileSpec &sfile_spec = supporting_files.GetFileSpecAtIndex(sfiles);
202c9af18a5SGreg Clayton                 const char *sfile_file_name = sfile_spec.GetFilename().GetCString();
203c9af18a5SGreg Clayton                 const char *sfile_dir_name = sfile_spec.GetFilename().GetCString();
204c9af18a5SGreg Clayton                 bool match = false;
205c9af18a5SGreg Clayton                 if (m_file_name && sfile_file_name
206c9af18a5SGreg Clayton                     && strstr (sfile_file_name, m_file_name) == sfile_file_name)
207c9af18a5SGreg Clayton                     match = true;
208c9af18a5SGreg Clayton                 if (match && m_dir_name && sfile_dir_name
209c9af18a5SGreg Clayton                     && strstr (sfile_dir_name, m_dir_name) != sfile_dir_name)
210c9af18a5SGreg Clayton                     match = false;
211c9af18a5SGreg Clayton 
212c9af18a5SGreg Clayton                 if (match)
213c9af18a5SGreg Clayton                 {
214c9af18a5SGreg Clayton                     m_matching_files.AppendIfUnique(sfile_spec);
215c9af18a5SGreg Clayton                 }
216c9af18a5SGreg Clayton             }
217c9af18a5SGreg Clayton 
218c9af18a5SGreg Clayton         }
219c9af18a5SGreg Clayton         else
220c9af18a5SGreg Clayton         {
221c9af18a5SGreg Clayton             const char *cur_file_name = context.comp_unit->GetFilename().GetCString();
222c9af18a5SGreg Clayton             const char *cur_dir_name = context.comp_unit->GetDirectory().GetCString();
223c9af18a5SGreg Clayton 
224c9af18a5SGreg Clayton             bool match = false;
225c9af18a5SGreg Clayton             if (m_file_name && cur_file_name
226c9af18a5SGreg Clayton                 && strstr (cur_file_name, m_file_name) == cur_file_name)
227c9af18a5SGreg Clayton                 match = true;
228c9af18a5SGreg Clayton 
229c9af18a5SGreg Clayton             if (match && m_dir_name && cur_dir_name
230c9af18a5SGreg Clayton                 && strstr (cur_dir_name, m_dir_name) != cur_dir_name)
231c9af18a5SGreg Clayton                 match = false;
232c9af18a5SGreg Clayton 
233c9af18a5SGreg Clayton             if (match)
234c9af18a5SGreg Clayton             {
235c9af18a5SGreg Clayton                 m_matching_files.AppendIfUnique(context.comp_unit);
236c9af18a5SGreg Clayton             }
237c9af18a5SGreg Clayton         }
238c9af18a5SGreg Clayton     }
239c9af18a5SGreg Clayton     return Searcher::eCallbackReturnContinue;
240c9af18a5SGreg Clayton }
241c9af18a5SGreg Clayton 
242c9af18a5SGreg Clayton size_t
243c9af18a5SGreg Clayton CommandCompletions::SourceFileCompleter::DoCompletion (SearchFilter *filter)
244c9af18a5SGreg Clayton {
245c9af18a5SGreg Clayton     filter->Search (*this);
246c9af18a5SGreg Clayton     // Now convert the filelist to completions:
247c9af18a5SGreg Clayton     for (size_t i = 0; i < m_matching_files.GetSize(); i++)
248c9af18a5SGreg Clayton     {
249c9af18a5SGreg Clayton         m_matches.AppendString (m_matching_files.GetFileSpecAtIndex(i).GetFilename().GetCString());
250c9af18a5SGreg Clayton     }
251c9af18a5SGreg Clayton     return m_matches.GetSize();
252c9af18a5SGreg Clayton 
253c9af18a5SGreg Clayton }
254c9af18a5SGreg Clayton 
255c9af18a5SGreg Clayton //----------------------------------------------------------------------
256c9af18a5SGreg Clayton // SymbolCompleter
257c9af18a5SGreg Clayton //----------------------------------------------------------------------
258c9af18a5SGreg Clayton 
259c9af18a5SGreg Clayton static bool
260c9af18a5SGreg Clayton regex_chars (const char comp)
261c9af18a5SGreg Clayton {
262c9af18a5SGreg Clayton     if (comp == '[' || comp == ']' || comp == '(' || comp == ')')
263c9af18a5SGreg Clayton         return true;
264c9af18a5SGreg Clayton     else
265c9af18a5SGreg Clayton         return false;
266c9af18a5SGreg Clayton }
267c9af18a5SGreg Clayton CommandCompletions::SymbolCompleter::SymbolCompleter (
268c9af18a5SGreg Clayton     const char *completion_str,
269c9af18a5SGreg Clayton     int match_start_point,
270c9af18a5SGreg Clayton     int max_return_elements,
271c9af18a5SGreg Clayton     CommandInterpreter *interpreter,
272c9af18a5SGreg Clayton     StringList &matches
273c9af18a5SGreg Clayton ) :
274c9af18a5SGreg Clayton     CommandCompletions::Completer (completion_str, match_start_point, max_return_elements, interpreter, matches)
275c9af18a5SGreg Clayton {
276c9af18a5SGreg Clayton     std::string regex_str ("^");
277c9af18a5SGreg Clayton     regex_str.append(completion_str);
278c9af18a5SGreg Clayton     regex_str.append(".*");
279c9af18a5SGreg Clayton     std::string::iterator pos;
280c9af18a5SGreg Clayton 
281c9af18a5SGreg Clayton     pos = find_if(regex_str.begin(), regex_str.end(), regex_chars);
282c9af18a5SGreg Clayton     while (pos < regex_str.end()) {
283c9af18a5SGreg Clayton         pos = regex_str.insert(pos, '\\');
284c9af18a5SGreg Clayton         pos += 2;
285c9af18a5SGreg Clayton         pos = find_if(pos, regex_str.end(), regex_chars);
286c9af18a5SGreg Clayton     }
287c9af18a5SGreg Clayton     m_regex.Compile(regex_str.c_str());
288c9af18a5SGreg Clayton }
289c9af18a5SGreg Clayton 
290c9af18a5SGreg Clayton Searcher::Depth
291c9af18a5SGreg Clayton CommandCompletions::SymbolCompleter::GetDepth()
292c9af18a5SGreg Clayton {
293c9af18a5SGreg Clayton     return eDepthModule;
294c9af18a5SGreg Clayton }
295c9af18a5SGreg Clayton 
296c9af18a5SGreg Clayton Searcher::CallbackReturn
297c9af18a5SGreg Clayton CommandCompletions::SymbolCompleter::SearchCallback (
298c9af18a5SGreg Clayton     SearchFilter &filter,
299c9af18a5SGreg Clayton     SymbolContext &context,
300c9af18a5SGreg Clayton     Address *addr,
301c9af18a5SGreg Clayton     bool complete
302c9af18a5SGreg Clayton )
303c9af18a5SGreg Clayton {
304c9af18a5SGreg Clayton     SymbolContextList func_list;
305c9af18a5SGreg Clayton     SymbolContextList sym_list;
306c9af18a5SGreg Clayton 
307c9af18a5SGreg Clayton     if (context.module_sp != NULL)
308c9af18a5SGreg Clayton     {
309c9af18a5SGreg Clayton         if (context.module_sp)
310c9af18a5SGreg Clayton         {
311c9af18a5SGreg Clayton             context.module_sp->FindSymbolsMatchingRegExAndType (m_regex, lldb::eSymbolTypeCode, sym_list);
312c9af18a5SGreg Clayton             context.module_sp->FindFunctions (m_regex, true, func_list);
313c9af18a5SGreg Clayton         }
314c9af18a5SGreg Clayton 
315c9af18a5SGreg Clayton         SymbolContext sc;
316c9af18a5SGreg Clayton         // Now add the functions & symbols to the list - only add if unique:
317c9af18a5SGreg Clayton         for (int i = 0; i < func_list.GetSize(); i++)
318c9af18a5SGreg Clayton         {
319c9af18a5SGreg Clayton             if (func_list.GetContextAtIndex(i, sc))
320c9af18a5SGreg Clayton             {
321c9af18a5SGreg Clayton                 if (sc.function)
322c9af18a5SGreg Clayton                 {
323c9af18a5SGreg Clayton                     m_match_set.insert (sc.function->GetMangled().GetDemangledName());
324c9af18a5SGreg Clayton                 }
325c9af18a5SGreg Clayton             }
326c9af18a5SGreg Clayton         }
327c9af18a5SGreg Clayton 
328c9af18a5SGreg Clayton         for (int i = 0; i < sym_list.GetSize(); i++)
329c9af18a5SGreg Clayton         {
330c9af18a5SGreg Clayton             if (sym_list.GetContextAtIndex(i, sc))
331c9af18a5SGreg Clayton             {
332c9af18a5SGreg Clayton                 if (sc.symbol && sc.symbol->GetAddressRangePtr())
333c9af18a5SGreg Clayton                 {
334c9af18a5SGreg Clayton                     m_match_set.insert (sc.symbol->GetMangled().GetDemangledName());
335c9af18a5SGreg Clayton                 }
336c9af18a5SGreg Clayton             }
337c9af18a5SGreg Clayton         }
338c9af18a5SGreg Clayton     }
339c9af18a5SGreg Clayton     return Searcher::eCallbackReturnContinue;
340c9af18a5SGreg Clayton }
341c9af18a5SGreg Clayton 
342c9af18a5SGreg Clayton size_t
343c9af18a5SGreg Clayton CommandCompletions::SymbolCompleter::DoCompletion (SearchFilter *filter)
344c9af18a5SGreg Clayton {
345c9af18a5SGreg Clayton     filter->Search (*this);
346c9af18a5SGreg Clayton     collection::iterator pos = m_match_set.begin(), end = m_match_set.end();
347c9af18a5SGreg Clayton     for (pos = m_match_set.begin(); pos != end; pos++)
348c9af18a5SGreg Clayton         m_matches.AppendString((*pos).GetCString());
349c9af18a5SGreg Clayton 
350c9af18a5SGreg Clayton     return m_matches.GetSize();
351c9af18a5SGreg Clayton }
352c9af18a5SGreg Clayton 
353c9af18a5SGreg Clayton //----------------------------------------------------------------------
354c9af18a5SGreg Clayton // ModuleCompleter
355c9af18a5SGreg Clayton //----------------------------------------------------------------------
356c9af18a5SGreg Clayton CommandCompletions::ModuleCompleter::ModuleCompleter (
357c9af18a5SGreg Clayton     const char *completion_str,
358c9af18a5SGreg Clayton     int match_start_point,
359c9af18a5SGreg Clayton     int max_return_elements,
360c9af18a5SGreg Clayton     CommandInterpreter *interpreter,
361c9af18a5SGreg Clayton     StringList &matches
362c9af18a5SGreg Clayton ) :
363c9af18a5SGreg Clayton     CommandCompletions::Completer (completion_str, match_start_point, max_return_elements, interpreter, matches)
364c9af18a5SGreg Clayton {
365c9af18a5SGreg Clayton     FileSpec partial_spec (m_completion_str.c_str());
366c9af18a5SGreg Clayton     m_file_name = partial_spec.GetFilename().GetCString();
367c9af18a5SGreg Clayton     m_dir_name = partial_spec.GetDirectory().GetCString();
368c9af18a5SGreg Clayton }
369c9af18a5SGreg Clayton 
370c9af18a5SGreg Clayton Searcher::Depth
371c9af18a5SGreg Clayton CommandCompletions::ModuleCompleter::GetDepth()
372c9af18a5SGreg Clayton {
373c9af18a5SGreg Clayton     return eDepthModule;
374c9af18a5SGreg Clayton }
375c9af18a5SGreg Clayton 
376c9af18a5SGreg Clayton Searcher::CallbackReturn
377c9af18a5SGreg Clayton CommandCompletions::ModuleCompleter::SearchCallback (
378c9af18a5SGreg Clayton     SearchFilter &filter,
379c9af18a5SGreg Clayton     SymbolContext &context,
380c9af18a5SGreg Clayton     Address *addr,
381c9af18a5SGreg Clayton     bool complete
382c9af18a5SGreg Clayton )
383c9af18a5SGreg Clayton {
384c9af18a5SGreg Clayton     if (context.module_sp != NULL)
385c9af18a5SGreg Clayton     {
386c9af18a5SGreg Clayton         const char *cur_file_name = context.module_sp->GetFileSpec().GetFilename().GetCString();
387c9af18a5SGreg Clayton         const char *cur_dir_name = context.module_sp->GetFileSpec().GetDirectory().GetCString();
388c9af18a5SGreg Clayton 
389c9af18a5SGreg Clayton         bool match = false;
390c9af18a5SGreg Clayton         if (m_file_name && cur_file_name
391c9af18a5SGreg Clayton             && strstr (cur_file_name, m_file_name) == cur_file_name)
392c9af18a5SGreg Clayton             match = true;
393c9af18a5SGreg Clayton 
394c9af18a5SGreg Clayton         if (match && m_dir_name && cur_dir_name
395c9af18a5SGreg Clayton             && strstr (cur_dir_name, m_dir_name) != cur_dir_name)
396c9af18a5SGreg Clayton             match = false;
397c9af18a5SGreg Clayton 
398c9af18a5SGreg Clayton         if (match)
399c9af18a5SGreg Clayton         {
400c9af18a5SGreg Clayton             m_matches.AppendString (cur_file_name);
401c9af18a5SGreg Clayton         }
402c9af18a5SGreg Clayton     }
403c9af18a5SGreg Clayton     return Searcher::eCallbackReturnContinue;
404c9af18a5SGreg Clayton }
405c9af18a5SGreg Clayton 
406c9af18a5SGreg Clayton size_t
407c9af18a5SGreg Clayton CommandCompletions::ModuleCompleter::DoCompletion (SearchFilter *filter)
408c9af18a5SGreg Clayton {
409c9af18a5SGreg Clayton     filter->Search (*this);
410c9af18a5SGreg Clayton     return m_matches.GetSize();
411c9af18a5SGreg Clayton }
412c9af18a5SGreg Clayton 
413c9af18a5SGreg Clayton 
414c9af18a5SGreg Clayton 
415