aboutsummaryrefslogtreecommitdiff
blob: 830cf36a7471ddd7a769220f714a600ba6632afb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
/* TID parsing for GDB, the GNU debugger.

   Copyright (C) 2015-2016 Free Software Foundation, Inc.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#ifndef TID_PARSE_H
#define TID_PARSE_H

#include "cli/cli-utils.h"

struct thread_info;

/* Issue an invalid thread ID error, pointing at STRING, the invalid
   ID.  */
extern void ATTRIBUTE_NORETURN invalid_thread_id_error (const char *string);

/* Parse TIDSTR as a per-inferior thread ID, in either INF_NUM.THR_NUM
   or THR_NUM form.  In the latter case, the missing INF_NUM is filled
   in from the current inferior.  If ENDPTR is not NULL,
   parse_thread_id stores the address of the first character after the
   thread ID.  Either a valid thread is returned, or an error is
   thrown.  */
struct thread_info *parse_thread_id (const char *tidstr, const char **end);

/* The possible states of the tid range parser's state machine.  */
enum tid_range_state
{
  /* Parsing the inferior number.  */
  TID_RANGE_STATE_INFERIOR,

  /* Parsing the thread number or thread number range.  */
  TID_RANGE_STATE_THREAD_RANGE,

  /* Parsing a star wildcard thread range.  E.g., "1.*".  */
  TID_RANGE_STATE_STAR_RANGE,
};

/* An object of this type is passed to tid_range_parser_get_tid.  It
   must be initialized by calling tid_range_parser_init.  This type is
   defined here so that it can be stack-allocated, but all members
   should be treated as opaque.  */
struct tid_range_parser
{
  /* What sub-component are we expecting.  */
  enum tid_range_state state;

  /* The string being parsed.  When parsing has finished, this points
     past the last parsed token.  */
  const char *string;

  /* The range parser state when we're parsing the thread number
     sub-component.  */
  struct get_number_or_range_state range_parser;

  /* Last inferior number returned.  */
  int inf_num;

  /* True if the TID last parsed was explicitly inferior-qualified.
     IOW, whether the spec specified an inferior number
     explicitly.  */
  int qualified;

  /* The inferior number to assume if the TID is not qualified.  */
  int default_inferior;
};

/* Initialize a tid_range_parser for use with
   tid_range_parser_get_tid.  TIDLIST is the string to be parsed.
   DEFAULT_INFERIOR is the inferior number to assume if a
   non-qualified thread ID is found.  */
extern void tid_range_parser_init (struct tid_range_parser *parser,
				   const char *tidlist,
				   int default_inferior);

/* Parse a thread ID or a thread range list.

   A range will be of the form

     <inferior_num>.<thread_number1>-<thread_number2>

   and will represent all the threads of inferior INFERIOR_NUM with
   number between THREAD_NUMBER1 and THREAD_NUMBER2, inclusive.
   <inferior_num> can also be omitted, as in

     <thread_number1>-<thread_number2>

   in which case GDB infers the inferior number from the default
   passed to the tid_range_parser_init function.

   This function is designed to be called iteratively.  While
   processing a thread ID range list, at each call it will return (in
   the INF_NUM and THR_NUM output parameters) the next thread ID in
   the range (irrespective of whether the thread actually exists).

   At the beginning of parsing a thread range, the char pointer
   PARSER->string will be advanced past <thread_number1> and left
   pointing at the '-' token.  Subsequent calls will not advance the
   pointer until the range is completed.  The call that completes the
   range will advance the pointer past <thread_number2>.

   This function advances through the input string for as long you
   call it.  Once the end of the input string is reached, a call to
   tid_range_parser_finished returns false (see below).

   E.g., with list: "1.2 3.4-6":

     1st call: *INF_NUM=1; *THR_NUM=2 (finished==0)
     2nd call: *INF_NUM=3; *THR_NUM=4 (finished==0)
     3rd call: *INF_NUM=3; *THR_NUM=5 (finished==0)
     4th call: *INF_NUM=3; *THR_NUM=6 (finished==1)

   Returns true if parsed a thread/range successfully, false
   otherwise.  */
extern int tid_range_parser_get_tid (struct tid_range_parser *parser,
				      int *inf_num, int *thr_num);

/* Like tid_range_parser_get_tid, but return a thread ID range per
   call, rather then a single thread ID.

   If the next element in the list is a single thread ID, then
   *THR_START and *THR_END are set to the same value.

   E.g.,. with list: "1.2 3.4-6"

     1st call: *INF_NUM=1; *THR_START=2; *THR_END=2 (finished==0)
     2nd call: *INF_NUM=3; *THR_START=4; *THR_END=6 (finished==1)

   Returns true if parsed a thread/range successfully, false
   otherwise.  */
extern int tid_range_parser_get_tid_range (struct tid_range_parser *parser,
					   int *inf_num,
					   int *thr_start, int *thr_end);

/* Returns non-zero if processing a star wildcard (e.g., "1.*")
   range.  */
extern int tid_range_parser_star_range (struct tid_range_parser *parser);

/* Returns non-zero if parsing has completed.  */
extern int tid_range_parser_finished (struct tid_range_parser *parser);

/* Return the string being parsed.  When parsing has finished, this
   points past the last parsed token.  */
const char *tid_range_parser_string (struct tid_range_parser *parser);

/* When parsing a range, advance past the final token in the range.  */
extern void tid_range_parser_skip (struct tid_range_parser *parser);

/* True if the TID last parsed was explicitly inferior-qualified.
   IOW, whether the spec specified an inferior number explicitly.  */
extern int tid_range_parser_qualified (struct tid_range_parser *parser);

/* Accept a string-form list of thread IDs such as is accepted by
   tid_range_parser_get_tid.  Return true if the INF_NUM.THR.NUM
   thread is in the list.  DEFAULT_INFERIOR is the inferior number to
   assume if a non-qualified thread ID is found in the list.

   By definition, an empty list includes all threads.  This is to be
   interpreted as typing a command such as "info threads" with no
   arguments.  */
extern int tid_is_in_list (const char *list, int default_inferior,
			   int inf_num, int thr_num);

#endif /* TID_PARSE_H */