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