Commit | Line | Data |
---|---|---|
c7c1b3e9 | 1 | /* Data structures and API for event locations in GDB. |
61baf725 | 2 | Copyright (C) 2013-2017 Free Software Foundation, Inc. |
c7c1b3e9 KS |
3 | |
4 | This file is part of GDB. | |
5 | ||
6 | This program is free software; you can redistribute it and/or modify | |
7 | it under the terms of the GNU General Public License as published by | |
8 | the Free Software Foundation; either version 3 of the License, or | |
9 | (at your option) any later version. | |
10 | ||
11 | This program is distributed in the hope that it will be useful, | |
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | GNU General Public License for more details. | |
15 | ||
16 | You should have received a copy of the GNU General Public License | |
17 | along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
18 | ||
19 | #include "defs.h" | |
20 | #include "gdb_assert.h" | |
21 | #include "location.h" | |
22 | #include "symtab.h" | |
23 | #include "language.h" | |
24 | #include "linespec.h" | |
25 | #include "cli/cli-utils.h" | |
26 | #include "probe.h" | |
27 | ||
28 | #include <ctype.h> | |
29 | #include <string.h> | |
30 | ||
31 | /* An event location used to set a stop event in the inferior. | |
32 | This structure is an amalgam of the various ways | |
33 | to specify where a stop event should be set. */ | |
34 | ||
35 | struct event_location | |
36 | { | |
37 | /* The type of this breakpoint specification. */ | |
38 | enum event_location_type type; | |
ebdad8fc | 39 | #define EL_TYPE(P) (P)->type |
c7c1b3e9 KS |
40 | |
41 | union | |
42 | { | |
43 | /* A generic "this is a string specification" for a location. | |
44 | This representation is used by both "normal" linespecs and | |
45 | probes. */ | |
46 | char *addr_string; | |
ebdad8fc KS |
47 | #define EL_LINESPEC(P) ((P)->u.addr_string) |
48 | #define EL_PROBE(P) ((P)->u.addr_string) | |
a06efdd6 KS |
49 | |
50 | /* An address in the inferior. */ | |
51 | CORE_ADDR address; | |
ebdad8fc | 52 | #define EL_ADDRESS(P) (P)->u.address |
00e52e53 KS |
53 | |
54 | /* An explicit location. */ | |
67994074 | 55 | struct explicit_location explicit_loc; |
ebdad8fc | 56 | #define EL_EXPLICIT(P) (&((P)->u.explicit_loc)) |
c7c1b3e9 KS |
57 | } u; |
58 | ||
59 | /* Cached string representation of this location. This is used, e.g., to | |
60 | save stop event locations to file. Malloc'd. */ | |
61 | char *as_string; | |
ebdad8fc | 62 | #define EL_STRING(P) ((P)->as_string) |
c7c1b3e9 KS |
63 | }; |
64 | ||
65 | /* See description in location.h. */ | |
66 | ||
67 | enum event_location_type | |
68 | event_location_type (const struct event_location *location) | |
69 | { | |
70 | return EL_TYPE (location); | |
71 | } | |
72 | ||
73 | /* See description in location.h. */ | |
74 | ||
00e52e53 | 75 | void |
67994074 | 76 | initialize_explicit_location (struct explicit_location *explicit_loc) |
00e52e53 | 77 | { |
67994074 KS |
78 | memset (explicit_loc, 0, sizeof (struct explicit_location)); |
79 | explicit_loc->line_offset.sign = LINE_OFFSET_UNKNOWN; | |
00e52e53 KS |
80 | } |
81 | ||
82 | /* See description in location.h. */ | |
83 | ||
ffc2605c | 84 | event_location_up |
c7c1b3e9 KS |
85 | new_linespec_location (char **linespec) |
86 | { | |
87 | struct event_location *location; | |
88 | ||
89 | location = XCNEW (struct event_location); | |
90 | EL_TYPE (location) = LINESPEC_LOCATION; | |
91 | if (*linespec != NULL) | |
92 | { | |
93 | char *p; | |
94 | char *orig = *linespec; | |
95 | ||
96 | linespec_lex_to_end (linespec); | |
97 | p = remove_trailing_whitespace (orig, *linespec); | |
98 | if ((p - orig) > 0) | |
99 | EL_LINESPEC (location) = savestring (orig, p - orig); | |
100 | } | |
ffc2605c | 101 | return event_location_up (location); |
c7c1b3e9 KS |
102 | } |
103 | ||
104 | /* See description in location.h. */ | |
105 | ||
106 | const char * | |
107 | get_linespec_location (const struct event_location *location) | |
108 | { | |
109 | gdb_assert (EL_TYPE (location) == LINESPEC_LOCATION); | |
110 | return EL_LINESPEC (location); | |
111 | } | |
112 | ||
113 | /* See description in location.h. */ | |
114 | ||
ffc2605c | 115 | event_location_up |
305e13e6 JB |
116 | new_address_location (CORE_ADDR addr, const char *addr_string, |
117 | int addr_string_len) | |
a06efdd6 KS |
118 | { |
119 | struct event_location *location; | |
120 | ||
121 | location = XCNEW (struct event_location); | |
122 | EL_TYPE (location) = ADDRESS_LOCATION; | |
123 | EL_ADDRESS (location) = addr; | |
305e13e6 JB |
124 | if (addr_string != NULL) |
125 | EL_STRING (location) = xstrndup (addr_string, addr_string_len); | |
ffc2605c | 126 | return event_location_up (location); |
a06efdd6 KS |
127 | } |
128 | ||
129 | /* See description in location.h. */ | |
130 | ||
131 | CORE_ADDR | |
132 | get_address_location (const struct event_location *location) | |
133 | { | |
134 | gdb_assert (EL_TYPE (location) == ADDRESS_LOCATION); | |
135 | return EL_ADDRESS (location); | |
136 | } | |
137 | ||
138 | /* See description in location.h. */ | |
139 | ||
305e13e6 JB |
140 | const char * |
141 | get_address_string_location (const struct event_location *location) | |
142 | { | |
143 | gdb_assert (EL_TYPE (location) == ADDRESS_LOCATION); | |
144 | return EL_STRING (location); | |
145 | } | |
146 | ||
147 | /* See description in location.h. */ | |
148 | ||
ffc2605c | 149 | event_location_up |
5b56227b KS |
150 | new_probe_location (const char *probe) |
151 | { | |
152 | struct event_location *location; | |
153 | ||
154 | location = XCNEW (struct event_location); | |
155 | EL_TYPE (location) = PROBE_LOCATION; | |
156 | if (probe != NULL) | |
157 | EL_PROBE (location) = xstrdup (probe); | |
ffc2605c | 158 | return event_location_up (location); |
5b56227b KS |
159 | } |
160 | ||
161 | /* See description in location.h. */ | |
162 | ||
163 | const char * | |
164 | get_probe_location (const struct event_location *location) | |
165 | { | |
166 | gdb_assert (EL_TYPE (location) == PROBE_LOCATION); | |
167 | return EL_PROBE (location); | |
168 | } | |
169 | ||
170 | /* See description in location.h. */ | |
171 | ||
ffc2605c | 172 | event_location_up |
67994074 | 173 | new_explicit_location (const struct explicit_location *explicit_loc) |
00e52e53 KS |
174 | { |
175 | struct event_location tmp; | |
176 | ||
177 | memset (&tmp, 0, sizeof (struct event_location)); | |
178 | EL_TYPE (&tmp) = EXPLICIT_LOCATION; | |
179 | initialize_explicit_location (EL_EXPLICIT (&tmp)); | |
67994074 | 180 | if (explicit_loc != NULL) |
00e52e53 | 181 | { |
67994074 | 182 | if (explicit_loc->source_filename != NULL) |
00e52e53 KS |
183 | { |
184 | EL_EXPLICIT (&tmp)->source_filename | |
67994074 | 185 | = explicit_loc->source_filename; |
00e52e53 KS |
186 | } |
187 | ||
67994074 | 188 | if (explicit_loc->function_name != NULL) |
00e52e53 | 189 | EL_EXPLICIT (&tmp)->function_name |
67994074 | 190 | = explicit_loc->function_name; |
00e52e53 | 191 | |
67994074 KS |
192 | if (explicit_loc->label_name != NULL) |
193 | EL_EXPLICIT (&tmp)->label_name = explicit_loc->label_name; | |
00e52e53 | 194 | |
67994074 KS |
195 | if (explicit_loc->line_offset.sign != LINE_OFFSET_UNKNOWN) |
196 | EL_EXPLICIT (&tmp)->line_offset = explicit_loc->line_offset; | |
00e52e53 KS |
197 | } |
198 | ||
199 | return copy_event_location (&tmp); | |
200 | } | |
201 | ||
202 | /* See description in location.h. */ | |
203 | ||
204 | struct explicit_location * | |
205 | get_explicit_location (struct event_location *location) | |
206 | { | |
207 | gdb_assert (EL_TYPE (location) == EXPLICIT_LOCATION); | |
208 | return EL_EXPLICIT (location); | |
209 | } | |
210 | ||
211 | /* See description in location.h. */ | |
212 | ||
213 | const struct explicit_location * | |
214 | get_explicit_location_const (const struct event_location *location) | |
215 | { | |
216 | gdb_assert (EL_TYPE (location) == EXPLICIT_LOCATION); | |
217 | return EL_EXPLICIT (location); | |
218 | } | |
219 | ||
220 | /* This convenience function returns a malloc'd string which | |
67994074 | 221 | represents the location in EXPLICIT_LOC. |
00e52e53 KS |
222 | |
223 | AS_LINESPEC is non-zero if this string should be a linespec. | |
224 | Otherwise it will be output in explicit form. */ | |
225 | ||
226 | static char * | |
227 | explicit_to_string_internal (int as_linespec, | |
67994074 | 228 | const struct explicit_location *explicit_loc) |
00e52e53 | 229 | { |
00e52e53 | 230 | int need_space = 0; |
d7e74731 PA |
231 | char space = as_linespec ? ':' : ' '; |
232 | string_file buf; | |
00e52e53 | 233 | |
67994074 | 234 | if (explicit_loc->source_filename != NULL) |
00e52e53 KS |
235 | { |
236 | if (!as_linespec) | |
d7e74731 PA |
237 | buf.puts ("-source "); |
238 | buf.puts (explicit_loc->source_filename); | |
00e52e53 KS |
239 | need_space = 1; |
240 | } | |
241 | ||
67994074 | 242 | if (explicit_loc->function_name != NULL) |
00e52e53 KS |
243 | { |
244 | if (need_space) | |
d7e74731 | 245 | buf.putc (space); |
00e52e53 | 246 | if (!as_linespec) |
d7e74731 PA |
247 | buf.puts ("-function "); |
248 | buf.puts (explicit_loc->function_name); | |
00e52e53 KS |
249 | need_space = 1; |
250 | } | |
251 | ||
67994074 | 252 | if (explicit_loc->label_name != NULL) |
00e52e53 KS |
253 | { |
254 | if (need_space) | |
d7e74731 | 255 | buf.putc (space); |
00e52e53 | 256 | if (!as_linespec) |
d7e74731 PA |
257 | buf.puts ("-label "); |
258 | buf.puts (explicit_loc->label_name); | |
00e52e53 KS |
259 | need_space = 1; |
260 | } | |
261 | ||
67994074 | 262 | if (explicit_loc->line_offset.sign != LINE_OFFSET_UNKNOWN) |
00e52e53 KS |
263 | { |
264 | if (need_space) | |
d7e74731 | 265 | buf.putc (space); |
00e52e53 | 266 | if (!as_linespec) |
d7e74731 PA |
267 | buf.puts ("-line "); |
268 | buf.printf ("%s%d", | |
269 | (explicit_loc->line_offset.sign == LINE_OFFSET_NONE ? "" | |
270 | : (explicit_loc->line_offset.sign | |
271 | == LINE_OFFSET_PLUS ? "+" : "-")), | |
272 | explicit_loc->line_offset.offset); | |
00e52e53 KS |
273 | } |
274 | ||
d7e74731 | 275 | return xstrdup (buf.c_str ()); |
00e52e53 KS |
276 | } |
277 | ||
278 | /* See description in location.h. */ | |
279 | ||
280 | char * | |
67994074 | 281 | explicit_location_to_string (const struct explicit_location *explicit_loc) |
00e52e53 | 282 | { |
67994074 | 283 | return explicit_to_string_internal (0, explicit_loc); |
00e52e53 KS |
284 | } |
285 | ||
286 | /* See description in location.h. */ | |
287 | ||
288 | char * | |
67994074 | 289 | explicit_location_to_linespec (const struct explicit_location *explicit_loc) |
00e52e53 | 290 | { |
67994074 | 291 | return explicit_to_string_internal (1, explicit_loc); |
00e52e53 KS |
292 | } |
293 | ||
294 | /* See description in location.h. */ | |
295 | ||
ffc2605c | 296 | event_location_up |
c7c1b3e9 KS |
297 | copy_event_location (const struct event_location *src) |
298 | { | |
299 | struct event_location *dst; | |
300 | ||
301 | dst = XCNEW (struct event_location); | |
302 | EL_TYPE (dst) = EL_TYPE (src); | |
303 | if (EL_STRING (src) != NULL) | |
304 | EL_STRING (dst) = xstrdup (EL_STRING (src)); | |
305 | ||
306 | switch (EL_TYPE (src)) | |
307 | { | |
308 | case LINESPEC_LOCATION: | |
309 | if (EL_LINESPEC (src) != NULL) | |
310 | EL_LINESPEC (dst) = xstrdup (EL_LINESPEC (src)); | |
311 | break; | |
312 | ||
a06efdd6 KS |
313 | case ADDRESS_LOCATION: |
314 | EL_ADDRESS (dst) = EL_ADDRESS (src); | |
315 | break; | |
316 | ||
00e52e53 KS |
317 | case EXPLICIT_LOCATION: |
318 | if (EL_EXPLICIT (src)->source_filename != NULL) | |
319 | EL_EXPLICIT (dst)->source_filename | |
320 | = xstrdup (EL_EXPLICIT (src)->source_filename); | |
321 | ||
322 | if (EL_EXPLICIT (src)->function_name != NULL) | |
323 | EL_EXPLICIT (dst)->function_name | |
324 | = xstrdup (EL_EXPLICIT (src)->function_name); | |
325 | ||
326 | if (EL_EXPLICIT (src)->label_name != NULL) | |
327 | EL_EXPLICIT (dst)->label_name = xstrdup (EL_EXPLICIT (src)->label_name); | |
328 | ||
329 | EL_EXPLICIT (dst)->line_offset = EL_EXPLICIT (src)->line_offset; | |
330 | break; | |
331 | ||
332 | ||
5b56227b KS |
333 | case PROBE_LOCATION: |
334 | if (EL_PROBE (src) != NULL) | |
335 | EL_PROBE (dst) = xstrdup (EL_PROBE (src)); | |
336 | break; | |
337 | ||
c7c1b3e9 KS |
338 | default: |
339 | gdb_assert_not_reached ("unknown event location type"); | |
340 | } | |
341 | ||
ffc2605c | 342 | return event_location_up (dst); |
c7c1b3e9 KS |
343 | } |
344 | ||
c7c1b3e9 | 345 | void |
8e9e35b1 | 346 | event_location_deleter::operator() (event_location *location) const |
c7c1b3e9 KS |
347 | { |
348 | if (location != NULL) | |
349 | { | |
350 | xfree (EL_STRING (location)); | |
351 | ||
352 | switch (EL_TYPE (location)) | |
353 | { | |
354 | case LINESPEC_LOCATION: | |
355 | xfree (EL_LINESPEC (location)); | |
356 | break; | |
357 | ||
a06efdd6 KS |
358 | case ADDRESS_LOCATION: |
359 | /* Nothing to do. */ | |
360 | break; | |
361 | ||
00e52e53 KS |
362 | case EXPLICIT_LOCATION: |
363 | xfree (EL_EXPLICIT (location)->source_filename); | |
364 | xfree (EL_EXPLICIT (location)->function_name); | |
365 | xfree (EL_EXPLICIT (location)->label_name); | |
366 | break; | |
367 | ||
5b56227b KS |
368 | case PROBE_LOCATION: |
369 | xfree (EL_PROBE (location)); | |
370 | break; | |
371 | ||
c7c1b3e9 KS |
372 | default: |
373 | gdb_assert_not_reached ("unknown event location type"); | |
374 | } | |
375 | ||
376 | xfree (location); | |
377 | } | |
378 | } | |
379 | ||
380 | /* See description in location.h. */ | |
381 | ||
382 | const char * | |
383 | event_location_to_string (struct event_location *location) | |
384 | { | |
385 | if (EL_STRING (location) == NULL) | |
386 | { | |
387 | switch (EL_TYPE (location)) | |
388 | { | |
389 | case LINESPEC_LOCATION: | |
390 | if (EL_LINESPEC (location) != NULL) | |
391 | EL_STRING (location) = xstrdup (EL_LINESPEC (location)); | |
392 | break; | |
393 | ||
a06efdd6 KS |
394 | case ADDRESS_LOCATION: |
395 | EL_STRING (location) | |
396 | = xstrprintf ("*%s", | |
397 | core_addr_to_string (EL_ADDRESS (location))); | |
398 | break; | |
399 | ||
00e52e53 KS |
400 | case EXPLICIT_LOCATION: |
401 | EL_STRING (location) | |
402 | = explicit_location_to_string (EL_EXPLICIT (location)); | |
403 | break; | |
404 | ||
5b56227b KS |
405 | case PROBE_LOCATION: |
406 | EL_STRING (location) = xstrdup (EL_PROBE (location)); | |
407 | break; | |
408 | ||
c7c1b3e9 KS |
409 | default: |
410 | gdb_assert_not_reached ("unknown event location type"); | |
411 | } | |
412 | } | |
413 | ||
414 | return EL_STRING (location); | |
415 | } | |
416 | ||
87f0e720 KS |
417 | /* A lexer for explicit locations. This function will advance INP |
418 | past any strings that it lexes. Returns a malloc'd copy of the | |
419 | lexed string or NULL if no lexing was done. */ | |
420 | ||
4b217cc7 | 421 | static gdb::unique_xmalloc_ptr<char> |
87f0e720 KS |
422 | explicit_location_lex_one (const char **inp, |
423 | const struct language_defn *language) | |
424 | { | |
425 | const char *start = *inp; | |
426 | ||
427 | if (*start == '\0') | |
428 | return NULL; | |
429 | ||
430 | /* If quoted, skip to the ending quote. */ | |
431 | if (strchr (get_gdb_linespec_parser_quote_characters (), *start)) | |
432 | { | |
433 | char quote_char = *start; | |
434 | ||
435 | /* If the input is not an Ada operator, skip to the matching | |
436 | closing quote and return the string. */ | |
437 | if (!(language->la_language == language_ada | |
438 | && quote_char == '\"' && is_ada_operator (start))) | |
439 | { | |
440 | const char *end = find_toplevel_char (start + 1, quote_char); | |
441 | ||
442 | if (end == NULL) | |
443 | error (_("Unmatched quote, %s."), start); | |
444 | *inp = end + 1; | |
4b217cc7 TT |
445 | return gdb::unique_xmalloc_ptr<char> (savestring (start + 1, |
446 | *inp - start - 2)); | |
87f0e720 KS |
447 | } |
448 | } | |
449 | ||
450 | /* If the input starts with '-' or '+', the string ends with the next | |
451 | whitespace or comma. */ | |
452 | if (*start == '-' || *start == '+') | |
453 | { | |
454 | while (*inp[0] != '\0' && *inp[0] != ',' && !isspace (*inp[0])) | |
455 | ++(*inp); | |
456 | } | |
457 | else | |
458 | { | |
459 | /* Handle numbers first, stopping at the next whitespace or ','. */ | |
460 | while (isdigit (*inp[0])) | |
461 | ++(*inp); | |
462 | if (*inp[0] == '\0' || isspace (*inp[0]) || *inp[0] == ',') | |
4b217cc7 TT |
463 | return gdb::unique_xmalloc_ptr<char> (savestring (start, |
464 | *inp - start)); | |
87f0e720 KS |
465 | |
466 | /* Otherwise stop at the next occurrence of whitespace, '\0', | |
467 | keyword, or ','. */ | |
468 | *inp = start; | |
469 | while ((*inp)[0] | |
470 | && (*inp)[0] != ',' | |
471 | && !(isspace ((*inp)[0]) | |
472 | || linespec_lexer_lex_keyword (&(*inp)[1]))) | |
473 | { | |
474 | /* Special case: C++ operator,. */ | |
475 | if (language->la_language == language_cplus | |
b31f9478 YQ |
476 | && strncmp (*inp, "operator", 8) == 0) |
477 | (*inp) += 8; | |
87f0e720 KS |
478 | ++(*inp); |
479 | } | |
480 | } | |
481 | ||
482 | if (*inp - start > 0) | |
4b217cc7 | 483 | return gdb::unique_xmalloc_ptr<char> (savestring (start, *inp - start)); |
87f0e720 KS |
484 | |
485 | return NULL; | |
486 | } | |
487 | ||
488 | /* See description in location.h. */ | |
489 | ||
ffc2605c | 490 | event_location_up |
87f0e720 KS |
491 | string_to_explicit_location (const char **argp, |
492 | const struct language_defn *language, | |
493 | int dont_throw) | |
494 | { | |
ffc2605c | 495 | event_location_up location; |
87f0e720 KS |
496 | |
497 | /* It is assumed that input beginning with '-' and a non-digit | |
eeb1af43 KS |
498 | character is an explicit location. "-p" is reserved, though, |
499 | for probe locations. */ | |
87f0e720 | 500 | if (argp == NULL |
e742d386 | 501 | || *argp == NULL |
87f0e720 | 502 | || *argp[0] != '-' |
eeb1af43 KS |
503 | || !isalpha ((*argp)[1]) |
504 | || ((*argp)[0] == '-' && (*argp)[1] == 'p')) | |
87f0e720 KS |
505 | return NULL; |
506 | ||
507 | location = new_explicit_location (NULL); | |
87f0e720 KS |
508 | |
509 | /* Process option/argument pairs. dprintf_command | |
510 | requires that processing stop on ','. */ | |
511 | while ((*argp)[0] != '\0' && (*argp)[0] != ',') | |
512 | { | |
513 | int len; | |
87f0e720 | 514 | const char *start; |
87f0e720 KS |
515 | |
516 | /* If *ARGP starts with a keyword, stop processing | |
517 | options. */ | |
518 | if (linespec_lexer_lex_keyword (*argp) != NULL) | |
519 | break; | |
520 | ||
521 | /* Mark the start of the string in case we need to rewind. */ | |
522 | start = *argp; | |
523 | ||
524 | /* Get the option string. */ | |
4b217cc7 TT |
525 | gdb::unique_xmalloc_ptr<char> opt |
526 | = explicit_location_lex_one (argp, language); | |
87f0e720 KS |
527 | |
528 | *argp = skip_spaces_const (*argp); | |
529 | ||
530 | /* Get the argument string. */ | |
4b217cc7 TT |
531 | gdb::unique_xmalloc_ptr<char> oarg |
532 | = explicit_location_lex_one (argp, language); | |
533 | bool have_oarg = oarg != NULL; | |
87f0e720 KS |
534 | *argp = skip_spaces_const (*argp); |
535 | ||
536 | /* Use the length of the option to allow abbreviations. */ | |
4b217cc7 | 537 | len = strlen (opt.get ()); |
87f0e720 KS |
538 | |
539 | /* All options have a required argument. Checking for this required | |
540 | argument is deferred until later. */ | |
4b217cc7 TT |
541 | if (strncmp (opt.get (), "-source", len) == 0) |
542 | EL_EXPLICIT (location)->source_filename = oarg.release (); | |
543 | else if (strncmp (opt.get (), "-function", len) == 0) | |
544 | EL_EXPLICIT (location)->function_name = oarg.release (); | |
545 | else if (strncmp (opt.get (), "-line", len) == 0) | |
87f0e720 | 546 | { |
4b217cc7 TT |
547 | if (have_oarg) |
548 | EL_EXPLICIT (location)->line_offset | |
549 | = linespec_parse_line_offset (oarg.get ()); | |
87f0e720 | 550 | } |
4b217cc7 TT |
551 | else if (strncmp (opt.get (), "-label", len) == 0) |
552 | EL_EXPLICIT (location)->label_name = oarg.release (); | |
87f0e720 KS |
553 | /* Only emit an "invalid argument" error for options |
554 | that look like option strings. */ | |
4b217cc7 | 555 | else if (opt.get ()[0] == '-' && !isdigit (opt.get ()[1])) |
87f0e720 KS |
556 | { |
557 | if (!dont_throw) | |
4b217cc7 | 558 | error (_("invalid explicit location argument, \"%s\""), opt.get ()); |
87f0e720 KS |
559 | } |
560 | else | |
561 | { | |
562 | /* End of the explicit location specification. | |
563 | Stop parsing and return whatever explicit location was | |
564 | parsed. */ | |
565 | *argp = start; | |
87f0e720 KS |
566 | return location; |
567 | } | |
568 | ||
569 | /* It's a little lame to error after the fact, but in this | |
570 | case, it provides a much better user experience to issue | |
571 | the "invalid argument" error before any missing | |
572 | argument error. */ | |
4b217cc7 TT |
573 | if (!have_oarg && !dont_throw) |
574 | error (_("missing argument for \"%s\""), opt.get ()); | |
87f0e720 KS |
575 | } |
576 | ||
577 | /* One special error check: If a source filename was given | |
578 | without offset, function, or label, issue an error. */ | |
579 | if (EL_EXPLICIT (location)->source_filename != NULL | |
580 | && EL_EXPLICIT (location)->function_name == NULL | |
581 | && EL_EXPLICIT (location)->label_name == NULL | |
582 | && (EL_EXPLICIT (location)->line_offset.sign == LINE_OFFSET_UNKNOWN) | |
583 | && !dont_throw) | |
584 | { | |
585 | error (_("Source filename requires function, label, or " | |
586 | "line offset.")); | |
587 | } | |
588 | ||
87f0e720 KS |
589 | return location; |
590 | } | |
591 | ||
c7c1b3e9 KS |
592 | /* See description in location.h. */ |
593 | ||
ffc2605c | 594 | event_location_up |
eeb1af43 KS |
595 | string_to_event_location_basic (char **stringp, |
596 | const struct language_defn *language) | |
c7c1b3e9 | 597 | { |
ffc2605c | 598 | event_location_up location; |
870f88f7 | 599 | const char *cs; |
c7c1b3e9 | 600 | |
eeb1af43 KS |
601 | /* Try the input as a probe spec. */ |
602 | cs = *stringp; | |
603 | if (cs != NULL && probe_linespec_to_ops (&cs) != NULL) | |
a06efdd6 | 604 | { |
eeb1af43 KS |
605 | location = new_probe_location (*stringp); |
606 | *stringp += strlen (*stringp); | |
a06efdd6 KS |
607 | } |
608 | else | |
609 | { | |
eeb1af43 KS |
610 | /* Try an address location. */ |
611 | if (*stringp != NULL && **stringp == '*') | |
5b56227b | 612 | { |
87f0e720 | 613 | const char *arg, *orig; |
eeb1af43 | 614 | CORE_ADDR addr; |
87f0e720 | 615 | |
87f0e720 | 616 | orig = arg = *stringp; |
eeb1af43 KS |
617 | addr = linespec_expression_to_pc (&arg); |
618 | location = new_address_location (addr, orig, arg - orig); | |
619 | *stringp += arg - orig; | |
620 | } | |
621 | else | |
622 | { | |
623 | /* Everything else is a linespec. */ | |
624 | location = new_linespec_location (stringp); | |
5b56227b | 625 | } |
a06efdd6 KS |
626 | } |
627 | ||
c7c1b3e9 | 628 | return location; |
eeb1af43 KS |
629 | } |
630 | ||
631 | /* See description in location.h. */ | |
632 | ||
ffc2605c | 633 | event_location_up |
eeb1af43 KS |
634 | string_to_event_location (char **stringp, |
635 | const struct language_defn *language) | |
636 | { | |
eeb1af43 KS |
637 | const char *arg, *orig; |
638 | ||
639 | /* Try an explicit location. */ | |
640 | orig = arg = *stringp; | |
ffc2605c | 641 | event_location_up location = string_to_explicit_location (&arg, language, 0); |
eeb1af43 KS |
642 | if (location != NULL) |
643 | { | |
644 | /* It was a valid explicit location. Advance STRINGP to | |
645 | the end of input. */ | |
646 | *stringp += arg - orig; | |
647 | } | |
648 | else | |
649 | { | |
650 | /* Everything else is a "basic" linespec, address, or probe | |
651 | location. */ | |
652 | location = string_to_event_location_basic (stringp, language); | |
653 | } | |
654 | ||
655 | return location; | |
c7c1b3e9 KS |
656 | } |
657 | ||
658 | /* See description in location.h. */ | |
659 | ||
660 | int | |
661 | event_location_empty_p (const struct event_location *location) | |
662 | { | |
663 | switch (EL_TYPE (location)) | |
664 | { | |
665 | case LINESPEC_LOCATION: | |
666 | /* Linespecs are never "empty." (NULL is a valid linespec) */ | |
667 | return 0; | |
668 | ||
a06efdd6 KS |
669 | case ADDRESS_LOCATION: |
670 | return 0; | |
671 | ||
00e52e53 KS |
672 | case EXPLICIT_LOCATION: |
673 | return (EL_EXPLICIT (location) == NULL | |
674 | || (EL_EXPLICIT (location)->source_filename == NULL | |
675 | && EL_EXPLICIT (location)->function_name == NULL | |
676 | && EL_EXPLICIT (location)->label_name == NULL | |
677 | && (EL_EXPLICIT (location)->line_offset.sign | |
678 | == LINE_OFFSET_UNKNOWN))); | |
679 | ||
5b56227b KS |
680 | case PROBE_LOCATION: |
681 | return EL_PROBE (location) == NULL; | |
682 | ||
c7c1b3e9 KS |
683 | default: |
684 | gdb_assert_not_reached ("unknown event location type"); | |
685 | } | |
686 | } | |
687 | ||
688 | /* See description in location.h. */ | |
689 | ||
690 | void | |
691 | set_event_location_string (struct event_location *location, | |
692 | const char *string) | |
693 | { | |
694 | xfree (EL_STRING (location)); | |
695 | EL_STRING (location) = string == NULL ? NULL : xstrdup (string); | |
696 | } |