| 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 |