1"""
2Test the lldb command line completion mechanism.
3"""
4
5
6
7import os
8from multiprocessing import Process
9import lldb
10from lldbsuite.test.decorators import *
11from lldbsuite.test.lldbtest import *
12from lldbsuite.test import lldbplatform
13from lldbsuite.test import lldbutil
14
15
16class CommandLineCompletionTestCase(TestBase):
17
18    NO_DEBUG_INFO_TESTCASE = True
19
20    @classmethod
21    def classCleanup(cls):
22        """Cleanup the test byproducts."""
23        try:
24            os.remove("child_send.txt")
25            os.remove("child_read.txt")
26        except:
27            pass
28
29    def test_at(self):
30        """Test that 'at' completes to 'attach '."""
31        self.complete_from_to('at', 'attach ')
32
33    def test_de(self):
34        """Test that 'de' completes to 'detach '."""
35        self.complete_from_to('de', 'detach ')
36
37    def test_frame_variable(self):
38        self.build()
39        self.main_source = "main.cpp"
40        self.main_source_spec = lldb.SBFileSpec(self.main_source)
41
42        (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(self,
43                                          '// Break here', self.main_source_spec)
44        self.assertState(process.GetState(), lldb.eStateStopped)
45
46        # Since CommandInterpreter has been corrected to update the current execution
47        # context at the beginning of HandleCompletion, we're here explicitly testing
48        # the scenario where "frame var" is completed without any preceding commands.
49
50        self.complete_from_to('frame variable fo',
51                              'frame variable fooo')
52        self.complete_from_to('frame variable fooo.',
53                              'frame variable fooo.')
54        self.complete_from_to('frame variable fooo.dd',
55                              'frame variable fooo.dd')
56
57        self.complete_from_to('frame variable ptr_fooo->',
58                              'frame variable ptr_fooo->')
59        self.complete_from_to('frame variable ptr_fooo->dd',
60                              'frame variable ptr_fooo->dd')
61
62        self.complete_from_to('frame variable cont',
63                              'frame variable container')
64        self.complete_from_to('frame variable container.',
65                              'frame variable container.MemberVar')
66        self.complete_from_to('frame variable container.Mem',
67                              'frame variable container.MemberVar')
68
69        self.complete_from_to('frame variable ptr_cont',
70                              'frame variable ptr_container')
71        self.complete_from_to('frame variable ptr_container->',
72                              'frame variable ptr_container->MemberVar')
73        self.complete_from_to('frame variable ptr_container->Mem',
74                              'frame variable ptr_container->MemberVar')
75
76    def test_process_attach_dash_dash_con(self):
77        """Test that 'process attach --con' completes to 'process attach --continue '."""
78        self.complete_from_to(
79            'process attach --con',
80            'process attach --continue ')
81
82    def test_process_launch_arch(self):
83        self.complete_from_to('process launch --arch ',
84                              ['mips',
85                               'arm64'])
86
87    def test_process_load(self):
88        self.build()
89        lldbutil.run_to_source_breakpoint(self, '// Break here', lldb.SBFileSpec("main.cpp"))
90        self.complete_from_to('process load Makef', 'process load Makefile')
91
92    @skipUnlessPlatform(["linux"])
93    def test_process_unload(self):
94        """Test the completion for "process unload <index>" """
95        # This tab completion should not work without a running process.
96        self.complete_from_to('process unload ',
97                              'process unload ')
98
99        self.build()
100        lldbutil.run_to_source_breakpoint(self, '// Break here', lldb.SBFileSpec("main.cpp"))
101        err = lldb.SBError()
102        self.process().LoadImage(lldb.SBFileSpec(self.getBuildArtifact("libshared.so")), err)
103        self.assertSuccess(err)
104
105        self.complete_from_to('process unload ',
106                              'process unload 0')
107
108        self.process().UnloadImage(0)
109        self.complete_from_to('process unload ',
110                              'process unload ')
111
112    def test_process_plugin_completion(self):
113        subcommands = ['attach -P', 'connect -p', 'launch -p']
114
115        for subcommand in subcommands:
116            self.complete_from_to('process ' + subcommand + ' mac',
117                                  'process ' + subcommand + ' mach-o-core')
118
119    def completions_contain_str(self, input, needle):
120        interp = self.dbg.GetCommandInterpreter()
121        match_strings = lldb.SBStringList()
122        num_matches = interp.HandleCompletion(input, len(input), 0, -1, match_strings)
123        found_needle = False
124        for match in match_strings:
125          if needle in match:
126            found_needle = True
127            break
128        self.assertTrue(found_needle, "Returned completions: " + "\n".join(match_strings))
129
130
131    @skipIfRemote
132    def test_common_completion_process_pid_and_name(self):
133        # The LLDB process itself and the process already attached to are both
134        # ignored by the process discovery mechanism, thus we need a process known
135        # to us here.
136        self.build()
137        server = self.spawnSubprocess(
138            self.getBuildArtifact("a.out"),
139            ["-x"], # Arg "-x" makes the subprocess wait for input thus it won't be terminated too early
140            install_remote=False)
141        self.assertIsNotNone(server)
142        pid = server.pid
143
144        self.completions_contain('process attach -p ', [str(pid)])
145        self.completions_contain('platform process attach -p ', [str(pid)])
146        self.completions_contain('platform process info ', [str(pid)])
147
148        self.completions_contain_str('process attach -n ', "a.out")
149        self.completions_contain_str('platform process attach -n ', "a.out")
150
151    def test_process_signal(self):
152        # The tab completion for "process signal"  won't work without a running process.
153        self.complete_from_to('process signal ',
154                              'process signal ')
155
156        # Test with a running process.
157        self.build()
158        self.main_source = "main.cpp"
159        self.main_source_spec = lldb.SBFileSpec(self.main_source)
160        lldbutil.run_to_source_breakpoint(self, '// Break here', self.main_source_spec)
161
162        self.complete_from_to('process signal ',
163                              'process signal SIG')
164        self.complete_from_to('process signal SIGPIP',
165                              'process signal SIGPIPE')
166        self.complete_from_to('process signal SIGA',
167                              ['SIGABRT',
168                               'SIGALRM'])
169
170    def test_ambiguous_long_opt(self):
171        self.completions_match('breakpoint modify --th',
172                               ['--thread-id',
173                                '--thread-index',
174                                '--thread-name'])
175
176    def test_disassemble_dash_f(self):
177        self.completions_match('disassemble -F ',
178                               ['default',
179                                'intel',
180                                'att'])
181
182    def test_plugin_load(self):
183        self.complete_from_to('plugin load ', [])
184
185    def test_log_enable(self):
186        self.complete_from_to('log enable ll', ['lldb'])
187        self.complete_from_to('log enable dw', ['dwarf'])
188        self.complete_from_to('log enable lldb al', ['all'])
189        self.complete_from_to('log enable lldb sym', ['symbol'])
190
191    def test_log_enable(self):
192        self.complete_from_to('log disable ll', ['lldb'])
193        self.complete_from_to('log disable dw', ['dwarf'])
194        self.complete_from_to('log disable lldb al', ['all'])
195        self.complete_from_to('log disable lldb sym', ['symbol'])
196
197    def test_log_list(self):
198        self.complete_from_to('log list ll', ['lldb'])
199        self.complete_from_to('log list dw', ['dwarf'])
200        self.complete_from_to('log list ll', ['lldb'])
201        self.complete_from_to('log list lldb dwa', ['dwarf'])
202
203    def test_quoted_command(self):
204        self.complete_from_to('"set',
205                              ['"settings" '])
206
207    def test_quoted_arg_with_quoted_command(self):
208        self.complete_from_to('"settings" "repl',
209                              ['"replace" '])
210
211    def test_quoted_arg_without_quoted_command(self):
212        self.complete_from_to('settings "repl',
213                              ['"replace" '])
214
215    def test_single_quote_command(self):
216        self.complete_from_to("'set",
217                              ["'settings' "])
218
219    def test_terminated_quote_command(self):
220        # This should not crash, but we don't get any
221        # reasonable completions from this.
222        self.complete_from_to("'settings'", [])
223
224    def test_process_launch_arch_arm(self):
225        self.complete_from_to('process launch --arch arm',
226                              ['arm64'])
227
228    def test_target_symbols_add_shlib(self):
229        # Doesn't seem to work, but at least it shouldn't crash.
230        self.complete_from_to('target symbols add --shlib ', [])
231
232    def test_log_file(self):
233        # Complete in our source directory which contains a 'main.cpp' file.
234        src_dir =  self.getSourceDir() + '/'
235        self.complete_from_to('log enable lldb expr -f ' + src_dir,
236                              ['main.cpp'])
237
238    def test_log_dir(self):
239        # Complete our source directory.
240        src_dir =  os.path.dirname(os.path.realpath(__file__))
241        self.complete_from_to('log enable lldb expr -f ' + src_dir,
242                              [src_dir + os.sep], turn_off_re_match=True)
243
244    # <rdar://problem/11052829>
245    def test_infinite_loop_while_completing(self):
246        """Test that 'process print hello\' completes to itself and does not infinite loop."""
247        self.complete_from_to('process print hello\\', 'process print hello\\',
248                              turn_off_re_match=True)
249
250    def test_watchpoint_co(self):
251        """Test that 'watchpoint co' completes to 'watchpoint command '."""
252        self.complete_from_to('watchpoint co', 'watchpoint command ')
253
254    def test_watchpoint_command_space(self):
255        """Test that 'watchpoint command ' completes to ['add', 'delete', 'list']."""
256        self.complete_from_to(
257            'watchpoint command ', [
258                'add', 'delete', 'list'])
259
260    def test_watchpoint_command_a(self):
261        """Test that 'watchpoint command a' completes to 'watchpoint command add '."""
262        self.complete_from_to(
263            'watchpoint command a',
264            'watchpoint command add ')
265
266    def test_watchpoint_set_ex(self):
267        """Test that 'watchpoint set ex' completes to 'watchpoint set expression '."""
268        self.complete_from_to(
269            'watchpoint set ex',
270            'watchpoint set expression ')
271
272    def test_watchpoint_set_var(self):
273        """Test that 'watchpoint set var' completes to 'watchpoint set variable '."""
274        self.complete_from_to('watchpoint set var', 'watchpoint set variable ')
275
276    def test_watchpoint_set_variable_foo(self):
277        self.build()
278        lldbutil.run_to_source_breakpoint(self, '// Break here', lldb.SBFileSpec("main.cpp"))
279        self.complete_from_to('watchpoint set variable fo', 'watchpoint set variable fooo')
280        # Only complete the first argument.
281        self.complete_from_to('watchpoint set variable fooo ', 'watchpoint set variable fooo ')
282
283    def test_help_fi(self):
284        """Test that 'help fi' completes to ['file', 'finish']."""
285        self.complete_from_to(
286            'help fi', [
287                'file', 'finish'])
288
289    def test_help_watchpoint_s(self):
290        """Test that 'help watchpoint s' completes to 'help watchpoint set '."""
291        self.complete_from_to('help watchpoint s', 'help watchpoint set ')
292
293    @expectedFailureNetBSD
294    def test_common_complete_watchpoint_ids(self):
295        subcommands = ['enable', 'disable', 'delete', 'modify', 'ignore']
296
297        # Completion should not work without a target.
298        for subcommand in subcommands:
299            self.complete_from_to('watchpoint ' + subcommand + ' ',
300                                  'watchpoint ' + subcommand + ' ')
301
302        # Create a process to provide a target and enable watchpoint setting.
303        self.build()
304        lldbutil.run_to_source_breakpoint(self, '// Break here', lldb.SBFileSpec("main.cpp"))
305
306        self.runCmd('watchpoint set variable ptr_fooo')
307        for subcommand in subcommands:
308            self.complete_from_to('watchpoint ' + subcommand + ' ', ['1'])
309
310    def test_settings_append_target_er(self):
311        """Test that 'settings append target.er' completes to 'settings append target.error-path'."""
312        self.complete_from_to(
313            'settings append target.er',
314            'settings append target.error-path')
315
316    def test_settings_insert_after_target_en(self):
317        """Test that 'settings insert-after target.env' completes to 'settings insert-after target.env-vars'."""
318        self.complete_from_to(
319            'settings insert-after target.env',
320            'settings insert-after target.env-vars')
321
322    def test_settings_insert_before_target_en(self):
323        """Test that 'settings insert-before target.env' completes to 'settings insert-before target.env-vars'."""
324        self.complete_from_to(
325            'settings insert-before target.env',
326            'settings insert-before target.env-vars')
327
328    def test_settings_replace_target_ru(self):
329        """Test that 'settings replace target.ru' completes to 'settings replace target.run-args'."""
330        self.complete_from_to(
331            'settings replace target.ru',
332            'settings replace target.run-args')
333
334    def test_settings_show_term(self):
335        self.complete_from_to(
336            'settings show term-',
337            'settings show term-width')
338
339    def test_settings_list_term(self):
340        self.complete_from_to(
341            'settings list term-',
342            'settings list term-width')
343
344    def test_settings_remove_term(self):
345        self.complete_from_to(
346            'settings remove term-',
347            'settings remove term-width')
348
349    def test_settings_s(self):
350        """Test that 'settings s' completes to ['set', 'show']."""
351        self.complete_from_to(
352            'settings s', [
353                'set', 'show'])
354
355    def test_settings_set_th(self):
356        """Test that 'settings set thread-f' completes to 'settings set thread-format'."""
357        self.complete_from_to('settings set thread-f', 'settings set thread-format')
358
359    def test_settings_s_dash(self):
360        """Test that 'settings set --g' completes to 'settings set --global'."""
361        self.complete_from_to('settings set --g', 'settings set --global')
362
363    def test_settings_clear_th(self):
364        """Test that 'settings clear thread-f' completes to 'settings clear thread-format'."""
365        self.complete_from_to(
366            'settings clear thread-f',
367            'settings clear thread-format')
368
369    def test_settings_set_ta(self):
370        """Test that 'settings set ta' completes to 'settings set target.'."""
371        self.complete_from_to(
372            'settings set target.ma',
373            'settings set target.max-')
374
375    def test_settings_set_target_exec(self):
376        """Test that 'settings set target.exec' completes to 'settings set target.exec-search-paths '."""
377        self.complete_from_to(
378            'settings set target.exec',
379            'settings set target.exec-search-paths')
380
381    def test_settings_set_target_pr(self):
382        """Test that 'settings set target.pr' completes to [
383        'target.prefer-dynamic-value', 'target.process.']."""
384        self.complete_from_to('settings set target.pr',
385                              ['target.prefer-dynamic-value',
386                               'target.process.'])
387
388    def test_settings_set_target_process(self):
389        """Test that 'settings set target.process' completes to 'settings set target.process.'."""
390        self.complete_from_to(
391            'settings set target.process',
392            'settings set target.process.')
393
394    def test_settings_set_target_process_dot(self):
395        """Test that 'settings set target.process.t' completes to 'settings set target.process.thread.'."""
396        self.complete_from_to(
397            'settings set target.process.thr',
398            'settings set target.process.thread.')
399
400    def test_settings_set_target_process_thread_dot(self):
401        """Test that 'settings set target.process.thread.' completes to [
402        'target.process.thread.step-avoid-regexp', 'target.process.thread.trace-thread']."""
403        self.complete_from_to('settings set target.process.thread.',
404                              ['target.process.thread.step-avoid-regexp',
405                               'target.process.thread.trace-thread'])
406
407    def test_thread_plan_discard(self):
408        self.build()
409        (_, _, thread, _) = lldbutil.run_to_source_breakpoint(self,
410                                          'ptr_foo', lldb.SBFileSpec("main.cpp"))
411        self.assertTrue(thread)
412        self.complete_from_to('thread plan discard ', 'thread plan discard ')
413
414        source_path = os.path.join(self.getSourceDir(), "thread_plan_script.py")
415        self.runCmd("command script import '%s'"%(source_path))
416        self.runCmd("thread step-scripted -C thread_plan_script.PushPlanStack")
417        self.complete_from_to('thread plan discard ', 'thread plan discard 1')
418        self.runCmd('thread plan discard 1')
419
420    def test_target_space(self):
421        """Test that 'target ' completes to ['create', 'delete', 'list',
422        'modules', 'select', 'stop-hook', 'variable']."""
423        self.complete_from_to('target ',
424                              ['create',
425                               'delete',
426                               'list',
427                               'modules',
428                               'select',
429                               'stop-hook',
430                               'variable'])
431
432    def test_target_modules_dump_line_table(self):
433        """Tests source file completion by completing the line-table argument."""
434        self.build()
435        self.dbg.CreateTarget(self.getBuildArtifact("a.out"))
436        self.complete_from_to('target modules dump line-table main.cp',
437                              ['main.cpp'])
438
439    def test_target_modules_load_aout(self):
440        """Tests modules completion by completing the target modules load argument."""
441        self.build()
442        self.dbg.CreateTarget(self.getBuildArtifact("a.out"))
443        self.complete_from_to('target modules load a.ou',
444                              ['a.out'])
445
446    def test_target_modules_search_paths_insert(self):
447        # Completion won't work without a valid target.
448        self.complete_from_to("target modules search-paths insert ", "target modules search-paths insert ")
449        self.build()
450        target = self.dbg.CreateTarget(self.getBuildArtifact('a.out'))
451        self.assertTrue(target, VALID_TARGET)
452        self.complete_from_to("target modules search-paths insert ", "target modules search-paths insert ")
453        self.runCmd("target modules search-paths add a b")
454        self.complete_from_to("target modules search-paths insert ", "target modules search-paths insert 0")
455        # Completion only works for the first arg.
456        self.complete_from_to("target modules search-paths insert 0 ", "target modules search-paths insert 0 ")
457
458    def test_target_create_dash_co(self):
459        """Test that 'target create --co' completes to 'target variable --core '."""
460        self.complete_from_to('target create --co', 'target create --core ')
461
462    def test_target_va(self):
463        """Test that 'target va' completes to 'target variable '."""
464        self.complete_from_to('target va', 'target variable ')
465
466    def test_common_completion_thread_index(self):
467        subcommands = ['continue', 'info', 'exception', 'select',
468                       'step-in', 'step-inst', 'step-inst-over', 'step-out', 'step-over', 'step-script']
469
470        # Completion should do nothing without threads.
471        for subcommand in subcommands:
472            self.complete_from_to('thread ' + subcommand + ' ',
473                                  'thread ' + subcommand + ' ')
474
475        self.build()
476        lldbutil.run_to_source_breakpoint(self, '// Break here', lldb.SBFileSpec("main.cpp"))
477
478        # At least we have the thread at the index of 1 now.
479        for subcommand in subcommands:
480            self.complete_from_to('thread ' + subcommand + ' ', ['1'])
481
482    def test_common_completion_type_category_name(self):
483        subcommands = ['delete', 'list', 'enable', 'disable', 'define']
484        for subcommand in subcommands:
485            self.complete_from_to('type category ' + subcommand + ' ', ['default'])
486        self.complete_from_to('type filter add -w ', ['default'])
487
488    def test_command_argument_completion(self):
489        """Test completion of command arguments"""
490        self.complete_from_to("watchpoint set variable -", ["-w", "-s"])
491        self.complete_from_to('watchpoint set variable -w', 'watchpoint set variable -w ')
492        self.complete_from_to("watchpoint set variable --", ["--watch", "--size"])
493        self.complete_from_to("watchpoint set variable --w", "watchpoint set variable --watch")
494        self.complete_from_to('watchpoint set variable -w ', ['read', 'write', 'read_write'])
495        self.complete_from_to("watchpoint set variable --watch ", ["read", "write", "read_write"])
496        self.complete_from_to("watchpoint set variable --watch w", "watchpoint set variable --watch write")
497        self.complete_from_to('watchpoint set variable -w read_', 'watchpoint set variable -w read_write')
498        # Now try the same thing with a variable name (non-option argument) to
499        # test that getopts arg reshuffling doesn't confuse us.
500        self.complete_from_to("watchpoint set variable foo -", ["-w", "-s"])
501        self.complete_from_to('watchpoint set variable foo -w', 'watchpoint set variable foo -w ')
502        self.complete_from_to("watchpoint set variable foo --", ["--watch", "--size"])
503        self.complete_from_to("watchpoint set variable foo --w", "watchpoint set variable foo --watch")
504        self.complete_from_to('watchpoint set variable foo -w ', ['read', 'write', 'read_write'])
505        self.complete_from_to("watchpoint set variable foo --watch ", ["read", "write", "read_write"])
506        self.complete_from_to("watchpoint set variable foo --watch w", "watchpoint set variable foo --watch write")
507        self.complete_from_to('watchpoint set variable foo -w read_', 'watchpoint set variable foo -w read_write')
508
509    def test_command_script_delete(self):
510        self.runCmd("command script add -h test_desc -f none -s current usercmd1")
511        self.check_completion_with_desc('command script delete ', [['usercmd1', '']])
512
513    def test_command_delete(self):
514        self.runCmd(r"command regex test_command s/^$/finish/ 's/([0-9]+)/frame select %1/'")
515        self.complete_from_to('command delete test_c', 'command delete test_command')
516
517    def test_command_unalias(self):
518        self.complete_from_to('command unalias ima', 'command unalias image')
519
520    def test_completion_description_commands(self):
521        """Test descriptions of top-level command completions"""
522        self.check_completion_with_desc("", [
523            ["command", "Commands for managing custom LLDB commands."],
524            ["breakpoint", "Commands for operating on breakpoints (see 'help b' for shorthand.)"]
525        ])
526
527        self.check_completion_with_desc("pl", [
528            ["platform", "Commands to manage and create platforms."],
529            ["plugin", "Commands for managing LLDB plugins."]
530        ])
531
532        # Just check that this doesn't crash.
533        self.check_completion_with_desc("comman", [])
534        self.check_completion_with_desc("non-existent-command", [])
535
536    def test_completion_description_command_options(self):
537        """Test descriptions of command options"""
538        # Short options
539        self.check_completion_with_desc("breakpoint set -", [
540            ["-h", "Set the breakpoint on exception catcH."],
541            ["-w", "Set the breakpoint on exception throW."]
542        ])
543
544        # Long options.
545        self.check_completion_with_desc("breakpoint set --", [
546            ["--on-catch", "Set the breakpoint on exception catcH."],
547            ["--on-throw", "Set the breakpoint on exception throW."]
548        ])
549
550        # Ambiguous long options.
551        self.check_completion_with_desc("breakpoint set --on-", [
552            ["--on-catch", "Set the breakpoint on exception catcH."],
553            ["--on-throw", "Set the breakpoint on exception throW."]
554        ])
555
556        # Unknown long option.
557        self.check_completion_with_desc("breakpoint set --Z", [
558        ])
559
560    def test_common_completion_frame_index(self):
561        self.build()
562        lldbutil.run_to_source_breakpoint(self, '// Break here', lldb.SBFileSpec("main.cpp"))
563
564        self.complete_from_to('frame select ', ['0'])
565        self.complete_from_to('thread backtrace -s ', ['0'])
566
567    def test_frame_recognizer_delete(self):
568        self.runCmd("frame recognizer add -l py_class -s module_name -n recognizer_name")
569        self.check_completion_with_desc('frame recognizer delete ', [['0', 'py_class, module module_name, symbol recognizer_name']])
570
571    def test_platform_install_local_file(self):
572        self.complete_from_to('platform target-install main.cp', 'platform target-install main.cpp')
573
574    @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24489")
575    def test_symbol_name(self):
576        self.build()
577        self.dbg.CreateTarget(self.getBuildArtifact("a.out"))
578        self.complete_from_to('breakpoint set -n Fo',
579                              'breakpoint set -n Foo::Bar(int,\\ int)',
580                              turn_off_re_match=True)
581        # No completion for Qu because the candidate is
582        # (anonymous namespace)::Quux().
583        self.complete_from_to('breakpoint set -n Qu', '')
584
585    def test_completion_type_formatter_delete(self):
586        self.runCmd('type filter add --child a Aoo')
587        self.complete_from_to('type filter delete ', ['Aoo'])
588        self.runCmd('type filter add --child b -x Boo')
589        self.complete_from_to('type filter delete ', ['Boo'])
590
591        self.runCmd('type format add -f hex Coo')
592        self.complete_from_to('type format delete ', ['Coo'])
593        self.runCmd('type format add -f hex -x Doo')
594        self.complete_from_to('type format delete ', ['Doo'])
595
596        self.runCmd('type summary add -c Eoo')
597        self.complete_from_to('type summary delete ', ['Eoo'])
598        self.runCmd('type summary add -x -c Foo')
599        self.complete_from_to('type summary delete ', ['Foo'])
600
601        self.runCmd('type synthetic add Goo -l test')
602        self.complete_from_to('type synthetic delete ', ['Goo'])
603        self.runCmd('type synthetic add -x Hoo -l test')
604        self.complete_from_to('type synthetic delete ', ['Hoo'])
605
606    @skipIf(archs=no_match(['x86_64']))
607    def test_register_read_and_write_on_x86(self):
608        """Test the completion of the commands register read and write on x86"""
609
610        # The tab completion for "register read/write"  won't work without a running process.
611        self.complete_from_to('register read ',
612                              'register read ')
613        self.complete_from_to('register write ',
614                              'register write ')
615
616        self.build()
617        self.main_source_spec = lldb.SBFileSpec("main.cpp")
618        lldbutil.run_to_source_breakpoint(self, '// Break here', self.main_source_spec)
619
620        # test cases for register read
621        self.complete_from_to('register read ',
622                              ['rax',
623                               'rbx',
624                               'rcx'])
625        self.complete_from_to('register read r',
626                              ['rax',
627                               'rbx',
628                               'rcx'])
629        self.complete_from_to('register read ra',
630                              'register read rax')
631        # register read can take multiple register names as arguments
632        self.complete_from_to('register read rax ',
633                              ['rax',
634                               'rbx',
635                               'rcx'])
636        # complete with prefix '$'
637        self.completions_match('register read $rb',
638                              ['$rbx',
639                               '$rbp'])
640        self.completions_match('register read $ra',
641                              ['$rax'])
642        self.complete_from_to('register read rax $',
643                              ['\$rax',
644                               '\$rbx',
645                               '\$rcx'])
646        self.complete_from_to('register read $rax ',
647                              ['rax',
648                               'rbx',
649                               'rcx'])
650
651        # test cases for register write
652        self.complete_from_to('register write ',
653                              ['rax',
654                               'rbx',
655                               'rcx'])
656        self.complete_from_to('register write r',
657                              ['rax',
658                               'rbx',
659                               'rcx'])
660        self.complete_from_to('register write ra',
661                              'register write rax')
662        self.complete_from_to('register write rb',
663                              ['rbx',
664                               'rbp'])
665        # register write can only take exact one register name as argument
666        self.complete_from_to('register write rbx ',
667                              [])
668
669    def test_common_completion_target_stophook_ids(self):
670        subcommands = ['delete', 'enable', 'disable']
671
672        for subcommand in subcommands:
673            self.complete_from_to('target stop-hook ' + subcommand + ' ',
674                                  'target stop-hook ' + subcommand + ' ')
675
676        self.build()
677        self.dbg.CreateTarget(self.getBuildArtifact("a.out"))
678        self.runCmd('target stop-hook add -o test')
679
680        for subcommand in subcommands:
681            self.complete_from_to('target stop-hook ' + subcommand + ' ',
682                                  'target stop-hook ' + subcommand + ' 1')
683
684        # Completion should work only on the first argument.
685        for subcommand in subcommands:
686            self.complete_from_to('target stop-hook ' + subcommand + ' 1 ',
687                                  'target stop-hook ' + subcommand + ' 1 ')
688
689    def test_common_completion_type_language(self):
690        self.complete_from_to('type category -l ', ['c'])
691
692    def test_target_modules_load_dash_u(self):
693        self.build()
694        target = self.dbg.CreateTarget(self.getBuildArtifact("a.out"))
695        self.complete_from_to('target modules load -u ', [target.GetModuleAtIndex(0).GetUUIDString()])
696
697    def test_complete_breakpoint_with_ids(self):
698        """These breakpoint subcommands should be completed with a list of breakpoint ids"""
699
700        subcommands = ['enable', 'disable', 'delete', 'modify', 'name add', 'name delete', 'write']
701
702        # The tab completion here is unavailable without a target
703        for subcommand in subcommands:
704            self.complete_from_to('breakpoint ' + subcommand + ' ',
705                                  'breakpoint ' + subcommand + ' ')
706
707        self.build()
708        target = self.dbg.CreateTarget(self.getBuildArtifact('a.out'))
709        self.assertTrue(target, VALID_TARGET)
710
711        bp = target.BreakpointCreateByName('main', 'a.out')
712        self.assertTrue(bp)
713        self.assertEqual(bp.GetNumLocations(), 1)
714
715        for subcommand in subcommands:
716            self.complete_from_to('breakpoint ' + subcommand + ' ',
717                                  ['1'])
718
719        bp2 = target.BreakpointCreateByName('Bar', 'a.out')
720        self.assertTrue(bp2)
721        self.assertEqual(bp2.GetNumLocations(), 1)
722
723        for subcommand in subcommands:
724            self.complete_from_to('breakpoint ' + subcommand + ' ',
725                                  ['1',
726                                   '2'])
727
728        for subcommand in subcommands:
729            self.complete_from_to('breakpoint ' + subcommand + ' 1 ',
730                                  ['1',
731                                   '2'])
732
733    def test_complete_breakpoint_with_names(self):
734        self.build()
735        target = self.dbg.CreateTarget(self.getBuildArtifact('a.out'))
736        self.assertTrue(target, VALID_TARGET)
737
738        # test breakpoint read dedicated
739        self.complete_from_to('breakpoint read -N ', 'breakpoint read -N ')
740        self.complete_from_to('breakpoint read -f breakpoints.json -N ', ['mm'])
741        self.complete_from_to('breakpoint read -f breakpoints.json -N n', 'breakpoint read -f breakpoints.json -N n')
742        self.complete_from_to('breakpoint read -f breakpoints_invalid.json -N ', 'breakpoint read -f breakpoints_invalid.json -N ')
743
744        # test common breapoint name completion
745        bp1 = target.BreakpointCreateByName('main', 'a.out')
746        self.assertTrue(bp1)
747        self.assertEqual(bp1.GetNumLocations(), 1)
748        self.complete_from_to('breakpoint set -N n', 'breakpoint set -N n')
749        self.assertTrue(bp1.AddNameWithErrorHandling("nn"))
750        self.complete_from_to('breakpoint set -N ', 'breakpoint set -N nn')
751