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