]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/skip.c
"backtrace full/no-filters/hide" completer
[thirdparty/binutils-gdb.git] / gdb / skip.c
CommitLineData
1bfeeb0f
JL
1/* Skipping uninteresting files and functions while stepping.
2
42a4f53d 3 Copyright (C) 2011-2019 Free Software Foundation, Inc.
1bfeeb0f
JL
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>. */
17
18#include "defs.h"
19#include "skip.h"
20#include "value.h"
21#include "valprint.h"
22#include "ui-out.h"
1bfeeb0f
JL
23#include "symtab.h"
24#include "gdbcmd.h"
25#include "command.h"
26#include "completer.h"
27#include "stack.h"
28#include "cli/cli-utils.h"
29#include "arch-utils.h"
30#include "linespec.h"
31#include "objfiles.h"
1bfeeb0f 32#include "breakpoint.h" /* for get_sal_arch () */
05cba821
JK
33#include "source.h"
34#include "filenames.h"
cce0e923
DE
35#include "fnmatch.h"
36#include "gdb_regex.h"
2d7cc5c7 37#include "common/gdb_optional.h"
de7985c3 38#include <list>
1bfeeb0f 39
3e68067f
SM
40/* True if we want to print debug printouts related to file/function
41 skipping. */
42static int debug_skip = 0;
43
de7985c3 44class skiplist_entry
1bfeeb0f 45{
de7985c3
PA
46public:
47 /* Create a skiplist_entry object and add it to the chain. */
48 static void add_entry (bool file_is_glob,
49 std::string &&file,
50 bool function_is_regexp,
51 std::string &&function);
52
53 /* Return true if the skip entry has a file or glob-style file
54 pattern that matches FUNCTION_SAL. */
55 bool skip_file_p (const symtab_and_line &function_sal) const;
56
57 /* Return true if the skip entry has a function or function regexp
58 that matches FUNCTION_NAME. */
59 bool skip_function_p (const char *function_name) const;
60
61 /* Getters. */
62 int number () const { return m_number; };
63 bool enabled () const { return m_enabled; };
64 bool file_is_glob () const { return m_file_is_glob; }
65 const std::string &file () const { return m_file; }
66 const std::string &function () const { return m_function; }
67 bool function_is_regexp () const { return m_function_is_regexp; }
68
69 /* Setters. */
70 void enable () { m_enabled = true; };
71 void disable () { m_enabled = false; };
72
73 /* Disable copy. */
74 skiplist_entry (const skiplist_entry &) = delete;
75 void operator= (const skiplist_entry &) = delete;
76
77private:
78 /* Key that grants access to the constructor. */
79 struct private_key {};
80public:
81 /* Public so we can construct with container::emplace_back. Since
82 it requires a private class key, it can't be called from outside.
83 Use the add_entry static factory method to construct instead. */
84 skiplist_entry (bool file_is_glob, std::string &&file,
85 bool function_is_regexp, std::string &&function,
86 private_key);
87
88private:
89 /* Return true if we're stopped at a file to be skipped. */
90 bool do_skip_file_p (const symtab_and_line &function_sal) const;
91
92 /* Return true if we're stopped at a globbed file to be skipped. */
93 bool do_skip_gfile_p (const symtab_and_line &function_sal) const;
94
95private: /* data */
96 int m_number = -1;
1bfeeb0f 97
42fa2e0e
TT
98 /* True if FILE is a glob-style pattern.
99 Otherwise it is the plain file name (possibly with directories). */
de7985c3 100 bool m_file_is_glob;
cce0e923 101
42fa2e0e 102 /* The name of the file or empty if no name. */
de7985c3 103 std::string m_file;
cce0e923 104
42fa2e0e 105 /* True if FUNCTION is a regexp.
cce0e923
DE
106 Otherwise it is a plain function name (possibly with arguments,
107 for C++). */
de7985c3 108 bool m_function_is_regexp;
1bfeeb0f 109
42fa2e0e 110 /* The name of the function or empty if no name. */
de7985c3 111 std::string m_function;
cce0e923
DE
112
113 /* If this is a function regexp, the compiled form. */
de7985c3 114 gdb::optional<compiled_regex> m_compiled_function_regexp;
1bfeeb0f 115
de7985c3
PA
116 /* Enabled/disabled state. */
117 bool m_enabled = true;
1bfeeb0f
JL
118};
119
de7985c3
PA
120static std::list<skiplist_entry> skiplist_entries;
121static int highest_skiplist_entry_num = 0;
122
123skiplist_entry::skiplist_entry (bool file_is_glob,
124 std::string &&file,
125 bool function_is_regexp,
126 std::string &&function,
127 private_key)
128 : m_file_is_glob (file_is_glob),
129 m_file (std::move (file)),
130 m_function_is_regexp (function_is_regexp),
131 m_function (std::move (function))
132{
133 gdb_assert (!m_file.empty () || !m_function.empty ());
1bfeeb0f 134
de7985c3
PA
135 if (m_file_is_glob)
136 gdb_assert (!m_file.empty ());
1bfeeb0f 137
de7985c3
PA
138 if (m_function_is_regexp)
139 {
140 gdb_assert (!m_function.empty ());
1bfeeb0f 141
de7985c3
PA
142 int flags = REG_NOSUB;
143#ifdef REG_EXTENDED
144 flags |= REG_EXTENDED;
145#endif
1bfeeb0f 146
de7985c3
PA
147 gdb_assert (!m_function.empty ());
148 m_compiled_function_regexp.emplace (m_function.c_str (), flags,
149 _("regexp"));
150 }
151}
cce0e923 152
de7985c3
PA
153void
154skiplist_entry::add_entry (bool file_is_glob, std::string &&file,
155 bool function_is_regexp, std::string &&function)
cce0e923 156{
de7985c3
PA
157 skiplist_entries.emplace_back (file_is_glob,
158 std::move (file),
159 function_is_regexp,
160 std::move (function),
161 private_key {});
162
163 /* Incremented after push_back, in case push_back throws. */
164 skiplist_entries.back ().m_number = ++highest_skiplist_entry_num;
cce0e923
DE
165}
166
1bfeeb0f 167static void
863779b0 168skip_file_command (const char *arg, int from_tty)
1bfeeb0f 169{
05cba821 170 struct symtab *symtab;
3d745be3 171 const char *filename = NULL;
1bfeeb0f
JL
172
173 /* If no argument was given, try to default to the last
174 displayed codepoint. */
3d745be3 175 if (arg == NULL)
1bfeeb0f
JL
176 {
177 symtab = get_last_displayed_symtab ();
3d745be3 178 if (symtab == NULL)
1bfeeb0f 179 error (_("No default file now."));
05cba821
JK
180
181 /* It is not a typo, symtab_to_filename_for_display woule be needlessly
182 ambiguous. */
183 filename = symtab_to_fullname (symtab);
1bfeeb0f
JL
184 }
185 else
cce0e923 186 filename = arg;
1bfeeb0f 187
de7985c3
PA
188 skiplist_entry::add_entry (false, std::string (filename),
189 false, std::string ());
1bfeeb0f
JL
190
191 printf_filtered (_("File %s will be skipped when stepping.\n"), filename);
192}
193
cce0e923
DE
194/* Create a skiplist entry for the given function NAME and add it to the
195 list. */
196
1bfeeb0f 197static void
cce0e923 198skip_function (const char *name)
1bfeeb0f 199{
de7985c3 200 skiplist_entry::add_entry (false, std::string (), false, std::string (name));
cce0e923
DE
201
202 printf_filtered (_("Function %s will be skipped when stepping.\n"), name);
203}
1bfeeb0f 204
cce0e923 205static void
863779b0 206skip_function_command (const char *arg, int from_tty)
cce0e923 207{
1bfeeb0f 208 /* Default to the current function if no argument is given. */
3d745be3 209 if (arg == NULL)
1bfeeb0f 210 {
cce0e923 211 const char *name = NULL;
1bfeeb0f 212 CORE_ADDR pc;
3d745be3 213
1bfeeb0f
JL
214 if (!last_displayed_sal_is_valid ())
215 error (_("No default function now."));
216
217 pc = get_last_displayed_addr ();
85817405 218 if (!find_pc_partial_function (pc, &name, NULL, NULL))
1bfeeb0f
JL
219 {
220 error (_("No function found containing current program point %s."),
221 paddress (get_current_arch (), pc));
222 }
85817405 223 skip_function (name);
cce0e923 224 return;
1bfeeb0f 225 }
cce0e923
DE
226
227 skip_function (arg);
228}
229
cce0e923
DE
230/* Process "skip ..." that does not match "skip file" or "skip function". */
231
232static void
981a3fb3 233skip_command (const char *arg, int from_tty)
cce0e923
DE
234{
235 const char *file = NULL;
236 const char *gfile = NULL;
237 const char *function = NULL;
238 const char *rfunction = NULL;
cce0e923
DE
239 int i;
240
241 if (arg == NULL)
242 {
243 skip_function_command (arg, from_tty);
244 return;
245 }
246
773a1edc 247 gdb_argv argv (arg);
cce0e923
DE
248
249 for (i = 0; argv[i] != NULL; ++i)
250 {
251 const char *p = argv[i];
252 const char *value = argv[i + 1];
253
254 if (strcmp (p, "-fi") == 0
255 || strcmp (p, "-file") == 0)
256 {
257 if (value == NULL)
258 error (_("Missing value for %s option."), p);
259 file = value;
260 ++i;
261 }
262 else if (strcmp (p, "-gfi") == 0
263 || strcmp (p, "-gfile") == 0)
264 {
265 if (value == NULL)
266 error (_("Missing value for %s option."), p);
267 gfile = value;
268 ++i;
269 }
270 else if (strcmp (p, "-fu") == 0
271 || strcmp (p, "-function") == 0)
272 {
273 if (value == NULL)
274 error (_("Missing value for %s option."), p);
275 function = value;
276 ++i;
277 }
278 else if (strcmp (p, "-rfu") == 0
279 || strcmp (p, "-rfunction") == 0)
280 {
281 if (value == NULL)
282 error (_("Missing value for %s option."), p);
283 rfunction = value;
284 ++i;
285 }
286 else if (*p == '-')
287 error (_("Invalid skip option: %s"), p);
288 else if (i == 0)
289 {
290 /* Assume the user entered "skip FUNCTION-NAME".
291 FUNCTION-NAME may be `foo (int)', and therefore we pass the
292 complete original arg to skip_function command as if the user
293 typed "skip function arg". */
cce0e923 294 skip_function_command (arg, from_tty);
1bfeeb0f
JL
295 return;
296 }
cce0e923
DE
297 else
298 error (_("Invalid argument: %s"), p);
299 }
300
301 if (file != NULL && gfile != NULL)
302 error (_("Cannot specify both -file and -gfile."));
303
304 if (function != NULL && rfunction != NULL)
305 error (_("Cannot specify both -function and -rfunction."));
306
307 /* This shouldn't happen as "skip" by itself gets punted to
308 skip_function_command. */
309 gdb_assert (file != NULL || gfile != NULL
310 || function != NULL || rfunction != NULL);
311
42fa2e0e
TT
312 std::string entry_file;
313 if (file != NULL)
314 entry_file = file;
315 else if (gfile != NULL)
316 entry_file = gfile;
de7985c3 317
42fa2e0e
TT
318 std::string entry_function;
319 if (function != NULL)
320 entry_function = function;
321 else if (rfunction != NULL)
322 entry_function = rfunction;
1bfeeb0f 323
de7985c3
PA
324 skiplist_entry::add_entry (gfile != NULL, std::move (entry_file),
325 rfunction != NULL, std::move (entry_function));
cce0e923
DE
326
327 /* I18N concerns drive some of the choices here (we can't piece together
328 the output too much). OTOH we want to keep this simple. Therefore the
329 only polish we add to the output is to append "(s)" to "File" or
330 "Function" if they're a glob/regexp. */
331 {
332 const char *file_to_print = file != NULL ? file : gfile;
333 const char *function_to_print = function != NULL ? function : rfunction;
334 const char *file_text = gfile != NULL ? _("File(s)") : _("File");
335 const char *lower_file_text = gfile != NULL ? _("file(s)") : _("file");
336 const char *function_text
337 = rfunction != NULL ? _("Function(s)") : _("Function");
338
339 if (function_to_print == NULL)
340 {
341 printf_filtered (_("%s %s will be skipped when stepping.\n"),
342 file_text, file_to_print);
343 }
344 else if (file_to_print == NULL)
345 {
346 printf_filtered (_("%s %s will be skipped when stepping.\n"),
347 function_text, function_to_print);
348 }
349 else
350 {
351 printf_filtered (_("%s %s in %s %s will be skipped"
352 " when stepping.\n"),
353 function_text, function_to_print,
354 lower_file_text, file_to_print);
355 }
356 }
1bfeeb0f
JL
357}
358
359static void
1d12d88f 360info_skip_command (const char *arg, int from_tty)
1bfeeb0f 361{
1bfeeb0f 362 int num_printable_entries = 0;
1bfeeb0f 363 struct value_print_options opts;
1bfeeb0f
JL
364
365 get_user_print_options (&opts);
366
367 /* Count the number of rows in the table and see if we need space for a
368 64-bit address anywhere. */
de7985c3
PA
369 for (const skiplist_entry &e : skiplist_entries)
370 if (arg == NULL || number_is_in_list (arg, e.number ()))
85817405 371 num_printable_entries++;
1bfeeb0f
JL
372
373 if (num_printable_entries == 0)
374 {
3d745be3 375 if (arg == NULL)
112e8700 376 current_uiout->message (_("Not skipping any files or functions.\n"));
1bfeeb0f 377 else
112e8700
SM
378 current_uiout->message (
379 _("No skiplist entries found with number %s.\n"), arg);
1bfeeb0f
JL
380
381 return;
382 }
383
4a2b031d
TT
384 ui_out_emit_table table_emitter (current_uiout, 6, num_printable_entries,
385 "SkiplistTable");
1bfeeb0f 386
112e8700
SM
387 current_uiout->table_header (5, ui_left, "number", "Num"); /* 1 */
388 current_uiout->table_header (3, ui_left, "enabled", "Enb"); /* 2 */
389 current_uiout->table_header (4, ui_right, "regexp", "Glob"); /* 3 */
390 current_uiout->table_header (20, ui_left, "file", "File"); /* 4 */
391 current_uiout->table_header (2, ui_right, "regexp", "RE"); /* 5 */
392 current_uiout->table_header (40, ui_noalign, "function", "Function"); /* 6 */
393 current_uiout->table_body ();
1bfeeb0f 394
de7985c3 395 for (const skiplist_entry &e : skiplist_entries)
1bfeeb0f 396 {
1bfeeb0f 397 QUIT;
de7985c3 398 if (arg != NULL && !number_is_in_list (arg, e.number ()))
1bfeeb0f
JL
399 continue;
400
2e783024 401 ui_out_emit_tuple tuple_emitter (current_uiout, "blklst-entry");
de7985c3 402 current_uiout->field_int ("number", e.number ()); /* 1 */
1bfeeb0f 403
de7985c3 404 if (e.enabled ())
112e8700 405 current_uiout->field_string ("enabled", "y"); /* 2 */
1bfeeb0f 406 else
112e8700 407 current_uiout->field_string ("enabled", "n"); /* 2 */
1bfeeb0f 408
de7985c3 409 if (e.file_is_glob ())
112e8700 410 current_uiout->field_string ("regexp", "y"); /* 3 */
1bfeeb0f 411 else
112e8700 412 current_uiout->field_string ("regexp", "n"); /* 3 */
1bfeeb0f 413
112e8700 414 current_uiout->field_string ("file",
de7985c3 415 e.file ().empty () ? "<none>"
cbe56571
TT
416 : e.file ().c_str (),
417 ui_out_style_kind::FILE); /* 4 */
de7985c3 418 if (e.function_is_regexp ())
112e8700 419 current_uiout->field_string ("regexp", "y"); /* 5 */
cce0e923 420 else
112e8700 421 current_uiout->field_string ("regexp", "n"); /* 5 */
cce0e923 422
42fa2e0e 423 current_uiout->field_string ("function",
de7985c3 424 e.function ().empty () ? "<none>"
cbe56571
TT
425 : e.function ().c_str (),
426 ui_out_style_kind::FUNCTION); /* 6 */
1bfeeb0f 427
112e8700 428 current_uiout->text ("\n");
1bfeeb0f 429 }
1bfeeb0f
JL
430}
431
432static void
863779b0 433skip_enable_command (const char *arg, int from_tty)
1bfeeb0f 434{
de7985c3 435 bool found = false;
1bfeeb0f 436
de7985c3
PA
437 for (skiplist_entry &e : skiplist_entries)
438 if (arg == NULL || number_is_in_list (arg, e.number ()))
1bfeeb0f 439 {
de7985c3
PA
440 e.enable ();
441 found = true;
1bfeeb0f
JL
442 }
443
444 if (!found)
445 error (_("No skiplist entries found with number %s."), arg);
446}
447
448static void
863779b0 449skip_disable_command (const char *arg, int from_tty)
1bfeeb0f 450{
de7985c3 451 bool found = false;
1bfeeb0f 452
de7985c3
PA
453 for (skiplist_entry &e : skiplist_entries)
454 if (arg == NULL || number_is_in_list (arg, e.number ()))
1bfeeb0f 455 {
de7985c3
PA
456 e.disable ();
457 found = true;
1bfeeb0f
JL
458 }
459
460 if (!found)
461 error (_("No skiplist entries found with number %s."), arg);
462}
463
464static void
863779b0 465skip_delete_command (const char *arg, int from_tty)
1bfeeb0f 466{
de7985c3 467 bool found = false;
1bfeeb0f 468
de7985c3
PA
469 for (auto it = skiplist_entries.begin (),
470 end = skiplist_entries.end ();
471 it != end;)
472 {
473 const skiplist_entry &e = *it;
1bfeeb0f 474
de7985c3
PA
475 if (arg == NULL || number_is_in_list (arg, e.number ()))
476 {
477 it = skiplist_entries.erase (it);
478 found = true;
479 }
480 else
481 ++it;
482 }
1bfeeb0f
JL
483
484 if (!found)
485 error (_("No skiplist entries found with number %s."), arg);
486}
487
de7985c3
PA
488bool
489skiplist_entry::do_skip_file_p (const symtab_and_line &function_sal) const
cce0e923 490{
3e68067f
SM
491 if (debug_skip)
492 fprintf_unfiltered (gdb_stdlog,
493 "skip: checking if file %s matches non-glob %s...",
494 function_sal.symtab->filename, m_file.c_str ());
495
496 bool result;
497
cce0e923
DE
498 /* Check first sole SYMTAB->FILENAME. It may not be a substring of
499 symtab_to_fullname as it may contain "./" etc. */
de7985c3
PA
500 if (compare_filenames_for_search (function_sal.symtab->filename,
501 m_file.c_str ()))
3e68067f 502 result = true;
cce0e923
DE
503
504 /* Before we invoke realpath, which can get expensive when many
505 files are involved, do a quick comparison of the basenames. */
3e68067f
SM
506 else if (!basenames_may_differ
507 && filename_cmp (lbasename (function_sal.symtab->filename),
508 lbasename (m_file.c_str ())) != 0)
509 result = false;
510 else
511 {
512 /* Note: symtab_to_fullname caches its result, thus we don't have to. */
513 const char *fullname = symtab_to_fullname (function_sal.symtab);
cce0e923 514
3e68067f
SM
515 result = compare_filenames_for_search (fullname, m_file.c_str ());
516 }
cce0e923 517
3e68067f
SM
518 if (debug_skip)
519 fprintf_unfiltered (gdb_stdlog, result ? "yes.\n" : "no.\n");
cce0e923 520
3e68067f 521 return result;
cce0e923
DE
522}
523
de7985c3
PA
524bool
525skiplist_entry::do_skip_gfile_p (const symtab_and_line &function_sal) const
cce0e923 526{
3e68067f
SM
527 if (debug_skip)
528 fprintf_unfiltered (gdb_stdlog,
529 "skip: checking if file %s matches glob %s...",
530 function_sal.symtab->filename, m_file.c_str ());
531
532 bool result;
533
cce0e923
DE
534 /* Check first sole SYMTAB->FILENAME. It may not be a substring of
535 symtab_to_fullname as it may contain "./" etc. */
de7985c3 536 if (gdb_filename_fnmatch (m_file.c_str (), function_sal.symtab->filename,
cce0e923 537 FNM_FILE_NAME | FNM_NOESCAPE) == 0)
3e68067f 538 result = true;
cce0e923
DE
539
540 /* Before we invoke symtab_to_fullname, which is expensive, do a quick
541 comparison of the basenames.
542 Note that we assume that lbasename works with glob-style patterns.
543 If the basename of the glob pattern is something like "*.c" then this
544 isn't much of a win. Oh well. */
3e68067f 545 else if (!basenames_may_differ
de7985c3
PA
546 && gdb_filename_fnmatch (lbasename (m_file.c_str ()),
547 lbasename (function_sal.symtab->filename),
cce0e923 548 FNM_FILE_NAME | FNM_NOESCAPE) != 0)
3e68067f
SM
549 result = false;
550 else
551 {
552 /* Note: symtab_to_fullname caches its result, thus we don't have to. */
553 const char *fullname = symtab_to_fullname (function_sal.symtab);
cce0e923 554
3e68067f
SM
555 result = compare_glob_filenames_for_search (fullname, m_file.c_str ());
556 }
cce0e923 557
3e68067f
SM
558 if (debug_skip)
559 fprintf_unfiltered (gdb_stdlog, result ? "yes.\n" : "no.\n");
cce0e923 560
3e68067f 561 return result;
cce0e923
DE
562}
563
de7985c3
PA
564bool
565skiplist_entry::skip_file_p (const symtab_and_line &function_sal) const
cce0e923 566{
de7985c3
PA
567 if (m_file.empty ())
568 return false;
cce0e923 569
de7985c3
PA
570 if (function_sal.symtab == NULL)
571 return false;
572
573 if (m_file_is_glob)
574 return do_skip_gfile_p (function_sal);
575 else
576 return do_skip_file_p (function_sal);
577}
cce0e923 578
de7985c3
PA
579bool
580skiplist_entry::skip_function_p (const char *function_name) const
cce0e923 581{
de7985c3
PA
582 if (m_function.empty ())
583 return false;
584
3e68067f
SM
585 bool result;
586
de7985c3
PA
587 if (m_function_is_regexp)
588 {
3e68067f
SM
589 if (debug_skip)
590 fprintf_unfiltered (gdb_stdlog,
591 "skip: checking if function %s matches regex %s...",
592 function_name, m_function.c_str ());
593
de7985c3 594 gdb_assert (m_compiled_function_regexp);
3e68067f
SM
595 result
596 = (m_compiled_function_regexp->exec (function_name, 0, NULL, 0) == 0);
de7985c3
PA
597 }
598 else
3e68067f
SM
599 {
600 if (debug_skip)
601 fprintf_unfiltered (gdb_stdlog,
602 ("skip: checking if function %s matches non-regex "
603 "%s..."),
604 function_name, m_function.c_str ());
605 result = (strcmp_iw (function_name, m_function.c_str ()) == 0);
606 }
607
608 if (debug_skip)
609 fprintf_unfiltered (gdb_stdlog, result ? "yes.\n" : "no.\n");
610
611 return result;
cce0e923 612}
85817405
JK
613
614/* See skip.h. */
1bfeeb0f 615
de7985c3 616bool
85817405 617function_name_is_marked_for_skip (const char *function_name,
de7985c3 618 const symtab_and_line &function_sal)
1bfeeb0f 619{
85817405 620 if (function_name == NULL)
de7985c3 621 return false;
85817405 622
de7985c3 623 for (const skiplist_entry &e : skiplist_entries)
1bfeeb0f 624 {
de7985c3 625 if (!e.enabled ())
1bfeeb0f
JL
626 continue;
627
de7985c3
PA
628 bool skip_by_file = e.skip_file_p (function_sal);
629 bool skip_by_function = e.skip_function_p (function_name);
cce0e923
DE
630
631 /* If both file and function must match, make sure we don't errantly
632 exit if only one of them match. */
de7985c3 633 if (!e.file ().empty () && !e.function ().empty ())
cce0e923
DE
634 {
635 if (skip_by_file && skip_by_function)
de7985c3 636 return true;
05cba821 637 }
cce0e923
DE
638 /* Only one of file/function is specified. */
639 else if (skip_by_file || skip_by_function)
de7985c3 640 return true;
1bfeeb0f
JL
641 }
642
de7985c3 643 return false;
1bfeeb0f
JL
644}
645
53a89d6e
SM
646/* Completer for skip numbers. */
647
648static void
649complete_skip_number (cmd_list_element *cmd,
650 completion_tracker &completer,
651 const char *text, const char *word)
652{
653 size_t word_len = strlen (word);
654
655 for (const skiplist_entry &entry : skiplist_entries)
656 {
657 gdb::unique_xmalloc_ptr<char> name (xstrprintf ("%d", entry.number ()));
658 if (strncmp (word, name.get (), word_len) == 0)
659 completer.add_completion (std::move (name));
660 }
661}
662
1bfeeb0f
JL
663void
664_initialize_step_skip (void)
665{
8bfd80db 666 static struct cmd_list_element *skiplist = NULL;
1bfeeb0f
JL
667 struct cmd_list_element *c;
668
cce0e923 669 add_prefix_cmd ("skip", class_breakpoint, skip_command, _("\
1bfeeb0f 670Ignore a function while stepping.\n\
cce0e923
DE
671\n\
672Usage: skip [FUNCTION-NAME]\n\
784e4b3e 673 skip [FILE-SPEC] [FUNCTION-SPEC]\n\
cce0e923
DE
674If no arguments are given, ignore the current function.\n\
675\n\
784e4b3e 676FILE-SPEC is one of:\n\
cce0e923
DE
677 -fi|-file FILE-NAME\n\
678 -gfi|-gfile GLOB-FILE-PATTERN\n\
784e4b3e 679FUNCTION-SPEC is one of:\n\
cce0e923
DE
680 -fu|-function FUNCTION-NAME\n\
681 -rfu|-rfunction FUNCTION-NAME-REGULAR-EXPRESSION"),
1bfeeb0f
JL
682 &skiplist, "skip ", 1, &cmdlist);
683
684 c = add_cmd ("file", class_breakpoint, skip_file_command, _("\
685Ignore a file while stepping.\n\
cce0e923 686Usage: skip file [FILE-NAME]\n\
1bfeeb0f
JL
687If no filename is given, ignore the current file."),
688 &skiplist);
689 set_cmd_completer (c, filename_completer);
690
691 c = add_cmd ("function", class_breakpoint, skip_function_command, _("\
692Ignore a function while stepping.\n\
cce0e923 693Usage: skip function [FUNCTION-NAME]\n\
1bfeeb0f
JL
694If no function name is given, skip the current function."),
695 &skiplist);
696 set_cmd_completer (c, location_completer);
697
53a89d6e 698 c = add_cmd ("enable", class_breakpoint, skip_enable_command, _("\
1bfeeb0f
JL
699Enable skip entries. You can specify numbers (e.g. \"skip enable 1 3\"), \
700ranges (e.g. \"skip enable 4-8\"), or both (e.g. \"skip enable 1 3 4-8\").\n\n\
701If you don't specify any numbers or ranges, we'll enable all skip entries.\n\n\
784e4b3e 702Usage: skip enable [NUMBER | RANGE]..."),
53a89d6e
SM
703 &skiplist);
704 set_cmd_completer (c, complete_skip_number);
1bfeeb0f 705
53a89d6e 706 c = add_cmd ("disable", class_breakpoint, skip_disable_command, _("\
1bfeeb0f
JL
707Disable skip entries. You can specify numbers (e.g. \"skip disable 1 3\"), \
708ranges (e.g. \"skip disable 4-8\"), or both (e.g. \"skip disable 1 3 4-8\").\n\n\
709If you don't specify any numbers or ranges, we'll disable all skip entries.\n\n\
784e4b3e 710Usage: skip disable [NUMBER | RANGE]..."),
53a89d6e
SM
711 &skiplist);
712 set_cmd_completer (c, complete_skip_number);
1bfeeb0f 713
53a89d6e 714 c = add_cmd ("delete", class_breakpoint, skip_delete_command, _("\
1bfeeb0f
JL
715Delete skip entries. You can specify numbers (e.g. \"skip delete 1 3\"), \
716ranges (e.g. \"skip delete 4-8\"), or both (e.g. \"skip delete 1 3 4-8\").\n\n\
717If you don't specify any numbers or ranges, we'll delete all skip entries.\n\n\
784e4b3e 718Usage: skip delete [NUMBER | RANGES]..."),
53a89d6e
SM
719 &skiplist);
720 set_cmd_completer (c, complete_skip_number);
1bfeeb0f 721
261f6f79
SM
722 add_info ("skip", info_skip_command, _("\
723Display the status of skips. You can specify numbers (e.g. \"info skip 1 3\"), \
724ranges (e.g. \"info skip 4-8\"), or both (e.g. \"info skip 1 3 4-8\").\n\n\
1bfeeb0f 725If you don't specify any numbers or ranges, we'll show all skips.\n\n\
261f6f79 726Usage: info skip [NUMBER | RANGES]..."));
53a89d6e 727 set_cmd_completer (c, complete_skip_number);
3e68067f
SM
728
729 add_setshow_boolean_cmd ("skip", class_maintenance,
730 &debug_skip, _("\
731Set whether to print the debug output about skipping files and functions."),
732 _("\
733Show whether the debug output about skipping files and functions is printed"),
734 _("\
735When non-zero, debug output about skipping files and functions is displayed."),
736 NULL, NULL,
737 &setdebuglist, &showdebuglist);
1bfeeb0f 738}