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