OLD | NEW |
1 /* MI Command Set - MI parser. | 1 /* MI Command Set - MI parser. |
2 | 2 |
3 Copyright (C) 2000-2002, 2007-2012 Free Software Foundation, Inc. | 3 Copyright (C) 2000-2002, 2007-2012 Free Software Foundation, Inc. |
4 | 4 |
5 Contributed by Cygnus Solutions (a Red Hat company). | 5 Contributed by Cygnus Solutions (a Red Hat company). |
6 | 6 |
7 This file is part of GDB. | 7 This file is part of GDB. |
8 | 8 |
9 This program is free software; you can redistribute it and/or modify | 9 This program is free software; you can redistribute it and/or modify |
10 it under the terms of the GNU General Public License as published by | 10 it under the terms of the GNU General Public License as published by |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
106 { | 106 { |
107 char *chp = args; | 107 char *chp = args; |
108 int argc = 0; | 108 int argc = 0; |
109 char **argv = xmalloc ((argc + 1) * sizeof (char *)); | 109 char **argv = xmalloc ((argc + 1) * sizeof (char *)); |
110 | 110 |
111 argv[argc] = NULL; | 111 argv[argc] = NULL; |
112 while (1) | 112 while (1) |
113 { | 113 { |
114 char *arg; | 114 char *arg; |
115 | 115 |
116 /* skip leading white space */ | 116 /* Skip leading white space. */ |
117 while (isspace (*chp)) | 117 while (isspace (*chp)) |
118 chp++; | 118 chp++; |
119 /* Three possibilities: EOF, quoted string, or other text. */ | 119 /* Three possibilities: EOF, quoted string, or other text. */ |
120 switch (*chp) | 120 switch (*chp) |
121 { | 121 { |
122 case '\0': | 122 case '\0': |
123 parse->argv = argv; | 123 parse->argv = argv; |
124 parse->argc = argc; | 124 parse->argc = argc; |
125 return; | 125 return; |
126 case '"': | 126 case '"': |
127 { | 127 { |
128 » /* A quoted string. */ | 128 » /* A quoted string. */ |
129 int len; | 129 int len; |
130 char *start = chp + 1; | 130 char *start = chp + 1; |
131 | 131 |
132 » /* Determine the buffer size. */ | 132 » /* Determine the buffer size. */ |
133 chp = start; | 133 chp = start; |
134 len = 0; | 134 len = 0; |
135 while (*chp != '\0' && *chp != '"') | 135 while (*chp != '\0' && *chp != '"') |
136 { | 136 { |
137 if (*chp == '\\') | 137 if (*chp == '\\') |
138 { | 138 { |
139 chp++; | 139 chp++; |
140 if (mi_parse_escape (&chp) <= 0) | 140 if (mi_parse_escape (&chp) <= 0) |
141 { | 141 { |
142 » » » /* Do not allow split lines or "\000" */ | 142 » » » /* Do not allow split lines or "\000". */ |
143 freeargv (argv); | 143 freeargv (argv); |
144 return; | 144 return; |
145 } | 145 } |
146 } | 146 } |
147 else | 147 else |
148 chp++; | 148 chp++; |
149 len++; | 149 len++; |
150 } | 150 } |
151 » /* Insist on a closing quote. */ | 151 » /* Insist on a closing quote. */ |
152 if (*chp != '"') | 152 if (*chp != '"') |
153 { | 153 { |
154 freeargv (argv); | 154 freeargv (argv); |
155 return; | 155 return; |
156 } | 156 } |
157 » /* Insist on trailing white space. */ | 157 » /* Insist on trailing white space. */ |
158 if (chp[1] != '\0' && !isspace (chp[1])) | 158 if (chp[1] != '\0' && !isspace (chp[1])) |
159 { | 159 { |
160 freeargv (argv); | 160 freeargv (argv); |
161 return; | 161 return; |
162 } | 162 } |
163 » /* create the buffer. */ | 163 » /* Create the buffer and copy characters in. */ |
164 arg = xmalloc ((len + 1) * sizeof (char)); | 164 arg = xmalloc ((len + 1) * sizeof (char)); |
165 /* And copy the characters in. */ | |
166 chp = start; | 165 chp = start; |
167 len = 0; | 166 len = 0; |
168 while (*chp != '\0' && *chp != '"') | 167 while (*chp != '\0' && *chp != '"') |
169 { | 168 { |
170 if (*chp == '\\') | 169 if (*chp == '\\') |
171 { | 170 { |
172 chp++; | 171 chp++; |
173 arg[len] = mi_parse_escape (&chp); | 172 arg[len] = mi_parse_escape (&chp); |
174 } | 173 } |
175 else | 174 else |
176 arg[len] = *chp++; | 175 arg[len] = *chp++; |
177 len++; | 176 len++; |
178 } | 177 } |
179 arg[len] = '\0'; | 178 arg[len] = '\0'; |
180 » chp++;» » /* that closing quote. */ | 179 » chp++;» » /* That closing quote. */ |
181 break; | 180 break; |
182 } | 181 } |
183 default: | 182 default: |
184 { | 183 { |
185 » /* An unquoted string. Accumulate all non blank | 184 » /* An unquoted string. Accumulate all non-blank |
186 » characters into a buffer. */ | 185 » characters into a buffer. */ |
187 int len; | 186 int len; |
188 char *start = chp; | 187 char *start = chp; |
189 | 188 |
190 while (*chp != '\0' && !isspace (*chp)) | 189 while (*chp != '\0' && !isspace (*chp)) |
191 { | 190 { |
192 chp++; | 191 chp++; |
193 } | 192 } |
194 len = chp - start; | 193 len = chp - start; |
195 arg = xmalloc ((len + 1) * sizeof (char)); | 194 arg = xmalloc ((len + 1) * sizeof (char)); |
196 strncpy (arg, start, len); | 195 strncpy (arg, start, len); |
197 arg[len] = '\0'; | 196 arg[len] = '\0'; |
198 break; | 197 break; |
199 } | 198 } |
200 } | 199 } |
201 /* Append arg to argv. */ | 200 /* Append arg to argv. */ |
202 argv = xrealloc (argv, (argc + 2) * sizeof (char *)); | 201 argv = xrealloc (argv, (argc + 2) * sizeof (char *)); |
203 argv[argc++] = arg; | 202 argv[argc++] = arg; |
204 argv[argc] = NULL; | 203 argv[argc] = NULL; |
205 } | 204 } |
206 } | 205 } |
207 | 206 |
208 | |
209 void | 207 void |
210 mi_parse_free (struct mi_parse *parse) | 208 mi_parse_free (struct mi_parse *parse) |
211 { | 209 { |
212 if (parse == NULL) | 210 if (parse == NULL) |
213 return; | 211 return; |
214 if (parse->command != NULL) | 212 if (parse->command != NULL) |
215 xfree (parse->command); | 213 xfree (parse->command); |
216 if (parse->token != NULL) | 214 if (parse->token != NULL) |
217 xfree (parse->token); | 215 xfree (parse->token); |
218 if (parse->args != NULL) | 216 if (parse->args != NULL) |
(...skipping 19 matching lines...) Expand all Loading... |
238 struct cleanup *cleanup; | 236 struct cleanup *cleanup; |
239 | 237 |
240 memset (parse, 0, sizeof (*parse)); | 238 memset (parse, 0, sizeof (*parse)); |
241 parse->all = 0; | 239 parse->all = 0; |
242 parse->thread_group = -1; | 240 parse->thread_group = -1; |
243 parse->thread = -1; | 241 parse->thread = -1; |
244 parse->frame = -1; | 242 parse->frame = -1; |
245 | 243 |
246 cleanup = make_cleanup (mi_parse_cleanup, parse); | 244 cleanup = make_cleanup (mi_parse_cleanup, parse); |
247 | 245 |
248 /* Before starting, skip leading white space. */ | 246 /* Before starting, skip leading white space. */ |
249 while (isspace (*cmd)) | 247 while (isspace (*cmd)) |
250 cmd++; | 248 cmd++; |
251 | 249 |
252 /* Find/skip any token and then extract it. */ | 250 /* Find/skip any token and then extract it. */ |
253 for (chp = cmd; *chp >= '0' && *chp <= '9'; chp++) | 251 for (chp = cmd; *chp >= '0' && *chp <= '9'; chp++) |
254 ; | 252 ; |
255 *token = xmalloc (chp - cmd + 1); | 253 *token = xmalloc (chp - cmd + 1); |
256 memcpy (*token, cmd, (chp - cmd)); | 254 memcpy (*token, cmd, (chp - cmd)); |
257 (*token)[chp - cmd] = '\0'; | 255 (*token)[chp - cmd] = '\0'; |
258 | 256 |
259 /* This wasn't a real MI command. Return it as a CLI_COMMAND. */ | 257 /* This wasn't a real MI command. Return it as a CLI_COMMAND. */ |
260 if (*chp != '-') | 258 if (*chp != '-') |
261 { | 259 { |
262 while (isspace (*chp)) | 260 while (isspace (*chp)) |
263 chp++; | 261 chp++; |
264 parse->command = xstrdup (chp); | 262 parse->command = xstrdup (chp); |
265 parse->op = CLI_COMMAND; | 263 parse->op = CLI_COMMAND; |
266 | 264 |
267 discard_cleanups (cleanup); | 265 discard_cleanups (cleanup); |
268 | 266 |
269 return parse; | 267 return parse; |
270 } | 268 } |
271 | 269 |
272 /* Extract the command. */ | 270 /* Extract the command. */ |
273 { | 271 { |
274 char *tmp = chp + 1; /* discard ``-'' */ | 272 char *tmp = chp + 1; /* discard ``-'' */ |
275 | 273 |
276 for (; *chp && !isspace (*chp); chp++) | 274 for (; *chp && !isspace (*chp); chp++) |
277 ; | 275 ; |
278 parse->command = xmalloc (chp - tmp + 1); | 276 parse->command = xmalloc (chp - tmp + 1); |
279 memcpy (parse->command, tmp, chp - tmp); | 277 memcpy (parse->command, tmp, chp - tmp); |
280 parse->command[chp - tmp] = '\0'; | 278 parse->command[chp - tmp] = '\0'; |
281 } | 279 } |
282 | 280 |
283 /* Find the command in the MI table. */ | 281 /* Find the command in the MI table. */ |
284 parse->cmd = mi_lookup (parse->command); | 282 parse->cmd = mi_lookup (parse->command); |
285 if (parse->cmd == NULL) | 283 if (parse->cmd == NULL) |
286 error (_("Undefined MI command: %s"), parse->command); | 284 error (_("Undefined MI command: %s"), parse->command); |
287 | 285 |
288 /* Skip white space following the command. */ | 286 /* Skip white space following the command. */ |
289 while (isspace (*chp)) | 287 while (isspace (*chp)) |
290 chp++; | 288 chp++; |
291 | 289 |
292 /* Parse the --thread and --frame options, if present. At present, | 290 /* Parse the --thread and --frame options, if present. At present, |
293 some important commands, like '-break-*' are implemented by forwarding | 291 some important commands, like '-break-*' are implemented by |
294 to the CLI layer directly. We want to parse --thread and --frame | 292 forwarding to the CLI layer directly. We want to parse --thread |
295 here, so as not to leave those option in the string that will be passed | 293 and --frame here, so as not to leave those option in the string |
296 to CLI. */ | 294 that will be passed to CLI. */ |
297 for (;;) | 295 for (;;) |
298 { | 296 { |
299 const char *option; | 297 const char *option; |
300 size_t as = sizeof ("--all ") - 1; | 298 size_t as = sizeof ("--all ") - 1; |
301 size_t tgs = sizeof ("--thread-group ") - 1; | 299 size_t tgs = sizeof ("--thread-group ") - 1; |
302 size_t ts = sizeof ("--thread ") - 1; | 300 size_t ts = sizeof ("--thread ") - 1; |
303 size_t fs = sizeof ("--frame ") - 1; | 301 size_t fs = sizeof ("--frame ") - 1; |
304 | 302 |
305 if (strncmp (chp, "--all ", as) == 0) | 303 if (strncmp (chp, "--all ", as) == 0) |
306 { | 304 { |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
343 else | 341 else |
344 break; | 342 break; |
345 | 343 |
346 if (*chp != '\0' && !isspace (*chp)) | 344 if (*chp != '\0' && !isspace (*chp)) |
347 error (_("Invalid value for the '%s' option"), option); | 345 error (_("Invalid value for the '%s' option"), option); |
348 while (isspace (*chp)) | 346 while (isspace (*chp)) |
349 chp++; | 347 chp++; |
350 } | 348 } |
351 | 349 |
352 /* For new argv commands, attempt to return the parsed argument | 350 /* For new argv commands, attempt to return the parsed argument |
353 list. */ | 351 list. */ |
354 if (parse->cmd->argv_func != NULL) | 352 if (parse->cmd->argv_func != NULL) |
355 { | 353 { |
356 mi_parse_argv (chp, parse); | 354 mi_parse_argv (chp, parse); |
357 if (parse->argv == NULL) | 355 if (parse->argv == NULL) |
358 error (_("Problem parsing arguments: %s %s"), parse->command, chp); | 356 error (_("Problem parsing arguments: %s %s"), parse->command, chp); |
359 } | 357 } |
360 | 358 |
361 /* FIXME: DELETE THIS */ | 359 /* FIXME: DELETE THIS */ |
362 /* For CLI commands, also return the remainder of the | 360 /* For CLI commands, also return the remainder of the |
363 command line as a single string. */ | 361 command line as a single string. */ |
364 if (parse->cmd->cli.cmd != NULL) | 362 if (parse->cmd->cli.cmd != NULL) |
365 parse->args = xstrdup (chp); | 363 parse->args = xstrdup (chp); |
366 | 364 |
367 discard_cleanups (cleanup); | 365 discard_cleanups (cleanup); |
368 | 366 |
369 /* Fully parsed. */ | 367 /* Fully parsed, flag as an MI command. */ |
370 parse->op = MI_COMMAND; | 368 parse->op = MI_COMMAND; |
371 return parse; | 369 return parse; |
372 } | 370 } |
OLD | NEW |