1 /* MI Command Set - file commands. 2 Copyright (C) 2000-2024 Free Software Foundation, Inc. 3 Contributed by Cygnus Solutions (a Red Hat company). 4 5 This file is part of GDB. 6 7 This program is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 3 of the License, or 10 (at your option) any later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 19 20 #include "mi-cmds.h" 21 #include "mi-getopt.h" 22 #include "mi-interp.h" 23 #include "ui-out.h" 24 #include "symtab.h" 25 #include "source.h" 26 #include "objfiles.h" 27 #include "solib.h" 28 #include "solist.h" 29 #include "gdbsupport/gdb_regex.h" 30 31 /* Return to the client the absolute path and line number of the 32 current file being executed. */ 33 34 void 35 mi_cmd_file_list_exec_source_file (const char *command, 36 const char *const *argv, int argc) 37 { 38 struct symtab_and_line st; 39 struct ui_out *uiout = current_uiout; 40 41 if (!mi_valid_noargs ("-file-list-exec-source-file", argc, argv)) 42 error (_("-file-list-exec-source-file: Usage: No args")); 43 44 /* Set the default file and line, also get them. */ 45 set_default_source_symtab_and_line (); 46 st = get_current_source_symtab_and_line (); 47 48 /* We should always get a symtab. Apparently, filename does not 49 need to be tested for NULL. The documentation in symtab.h 50 suggests it will always be correct. */ 51 if (!st.symtab) 52 error (_("-file-list-exec-source-file: No symtab")); 53 54 /* Print to the user the line, filename and fullname. */ 55 uiout->field_signed ("line", st.line); 56 uiout->field_string ("file", symtab_to_filename_for_display (st.symtab)); 57 58 uiout->field_string ("fullname", symtab_to_fullname (st.symtab)); 59 60 uiout->field_signed ("macro-info", 61 st.symtab->compunit ()->macro_table () != NULL); 62 } 63 64 /* Implement -file-list-exec-source-files command. */ 65 66 void 67 mi_cmd_file_list_exec_source_files (const char *command, 68 const char *const *argv, int argc) 69 { 70 enum opt 71 { 72 GROUP_BY_OBJFILE_OPT, 73 MATCH_BASENAME_OPT, 74 MATCH_DIRNAME_OPT 75 }; 76 static const struct mi_opt opts[] = 77 { 78 {"-group-by-objfile", GROUP_BY_OBJFILE_OPT, 0}, 79 {"-basename", MATCH_BASENAME_OPT, 0}, 80 {"-dirname", MATCH_DIRNAME_OPT, 0}, 81 { 0, 0, 0 } 82 }; 83 84 /* Parse arguments. */ 85 int oind = 0; 86 const char *oarg; 87 88 bool group_by_objfile = false; 89 bool match_on_basename = false; 90 bool match_on_dirname = false; 91 92 while (1) 93 { 94 int opt = mi_getopt ("-file-list-exec-source-files", argc, argv, 95 opts, &oind, &oarg); 96 if (opt < 0) 97 break; 98 switch ((enum opt) opt) 99 { 100 case GROUP_BY_OBJFILE_OPT: 101 group_by_objfile = true; 102 break; 103 case MATCH_BASENAME_OPT: 104 match_on_basename = true; 105 break; 106 case MATCH_DIRNAME_OPT: 107 match_on_dirname = true; 108 break; 109 } 110 } 111 112 if ((argc - oind > 1) || (match_on_basename && match_on_dirname)) 113 error (_("-file-list-exec-source-files: Usage: [--group-by-objfile] [--basename | --dirname] [--] REGEXP")); 114 115 const char *regexp = nullptr; 116 if (argc - oind == 1) 117 regexp = argv[oind]; 118 119 info_sources_filter::match_on match_type; 120 if (match_on_dirname) 121 match_type = info_sources_filter::match_on::DIRNAME; 122 else if (match_on_basename) 123 match_type = info_sources_filter::match_on::BASENAME; 124 else 125 match_type = info_sources_filter::match_on::FULLNAME; 126 127 info_sources_filter filter (match_type, regexp); 128 info_sources_worker (current_uiout, group_by_objfile, filter); 129 } 130 131 /* See mi-cmds.h. */ 132 133 void 134 mi_cmd_file_list_shared_libraries (const char *command, 135 const char *const *argv, int argc) 136 { 137 struct ui_out *uiout = current_uiout; 138 const char *pattern; 139 140 switch (argc) 141 { 142 case 0: 143 pattern = NULL; 144 break; 145 case 1: 146 pattern = argv[0]; 147 break; 148 default: 149 error (_("Usage: -file-list-shared-libraries [REGEXP]")); 150 } 151 152 if (pattern != NULL) 153 { 154 const char *re_err = re_comp (pattern); 155 156 if (re_err != NULL) 157 error (_("Invalid regexp: %s"), re_err); 158 } 159 160 update_solib_list (1); 161 162 /* Print the table header. */ 163 ui_out_emit_list list_emitter (uiout, "shared-libraries"); 164 165 for (const solib &so : current_program_space->solibs ()) 166 { 167 if (so.so_name.empty ()) 168 continue; 169 170 if (pattern != nullptr && !re_exec (so.so_name.c_str ())) 171 continue; 172 173 ui_out_emit_tuple tuple_emitter (uiout, NULL); 174 mi_output_solib_attribs (uiout, so); 175 } 176 } 177