OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gdb-7.2/] [gdb/] [mi/] [mi-parse.c] - Blame information for rev 853

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 330 jeremybenn
/* MI Command Set - MI parser.
2
 
3
   Copyright (C) 2000, 2001, 2002, 2007, 2008, 2009, 2010
4
   Free Software Foundation, Inc.
5
 
6
   Contributed by Cygnus Solutions (a Red Hat company).
7
 
8
   This file is part of GDB.
9
 
10
   This program is free software; you can redistribute it and/or modify
11
   it under the terms of the GNU General Public License as published by
12
   the Free Software Foundation; either version 3 of the License, or
13
   (at your option) any later version.
14
 
15
   This program is distributed in the hope that it will be useful,
16
   but WITHOUT ANY WARRANTY; without even the implied warranty of
17
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
   GNU General Public License for more details.
19
 
20
   You should have received a copy of the GNU General Public License
21
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
22
 
23
#include "defs.h"
24
#include "mi-cmds.h"
25
#include "mi-parse.h"
26
#include "charset.h"
27
 
28
#include <ctype.h>
29
#include "gdb_string.h"
30
 
31
/* Like parse_escape, but leave the results as a host char, not a
32
   target char.  */
33
 
34
static int
35
mi_parse_escape (char **string_ptr)
36
{
37
  int c = *(*string_ptr)++;
38
 
39
  switch (c)
40
    {
41
      case '\n':
42
        return -2;
43
      case 0:
44
        (*string_ptr)--;
45
        return 0;
46
 
47
      case '0':
48
      case '1':
49
      case '2':
50
      case '3':
51
      case '4':
52
      case '5':
53
      case '6':
54
      case '7':
55
        {
56
          int i = host_hex_value (c);
57
          int count = 0;
58
 
59
          while (++count < 3)
60
            {
61
              c = (**string_ptr);
62
              if (isdigit (c) && c != '8' && c != '9')
63
                {
64
                  (*string_ptr)++;
65
                  i *= 8;
66
                  i += host_hex_value (c);
67
                }
68
              else
69
                {
70
                  break;
71
                }
72
            }
73
          return i;
74
        }
75
 
76
    case 'a':
77
      c = '\a';
78
      break;
79
    case 'b':
80
      c = '\b';
81
      break;
82
    case 'f':
83
      c = '\f';
84
      break;
85
    case 'n':
86
      c = '\n';
87
      break;
88
    case 'r':
89
      c = '\r';
90
      break;
91
    case 't':
92
      c = '\t';
93
      break;
94
    case 'v':
95
      c = '\v';
96
      break;
97
 
98
    default:
99
      break;
100
    }
101
 
102
  return c;
103
}
104
 
105
static void
106
mi_parse_argv (char *args, struct mi_parse *parse)
107
{
108
  char *chp = args;
109
  int argc = 0;
110
  char **argv = xmalloc ((argc + 1) * sizeof (char *));
111
 
112
  argv[argc] = NULL;
113
  while (1)
114
    {
115
      char *arg;
116
 
117
      /* skip leading white space */
118
      while (isspace (*chp))
119
        chp++;
120
      /* Three possibilities: EOF, quoted string, or other text. */
121
      switch (*chp)
122
        {
123
        case '\0':
124
          parse->argv = argv;
125
          parse->argc = argc;
126
          return;
127
        case '"':
128
          {
129
            /* A quoted string. */
130
            int len;
131
            char *start = chp + 1;
132
 
133
            /* Determine the buffer size. */
134
            chp = start;
135
            len = 0;
136
            while (*chp != '\0' && *chp != '"')
137
              {
138
                if (*chp == '\\')
139
                  {
140
                    chp++;
141
                    if (mi_parse_escape (&chp) <= 0)
142
                      {
143
                        /* Do not allow split lines or "\000" */
144
                        freeargv (argv);
145
                        return;
146
                      }
147
                  }
148
                else
149
                  chp++;
150
                len++;
151
              }
152
            /* Insist on a closing quote. */
153
            if (*chp != '"')
154
              {
155
                freeargv (argv);
156
                return;
157
              }
158
            /* Insist on trailing white space. */
159
            if (chp[1] != '\0' && !isspace (chp[1]))
160
              {
161
                freeargv (argv);
162
                return;
163
              }
164
            /* create the buffer. */
165
            arg = xmalloc ((len + 1) * sizeof (char));
166
            /* And copy the characters in. */
167
            chp = start;
168
            len = 0;
169
            while (*chp != '\0' && *chp != '"')
170
              {
171
                if (*chp == '\\')
172
                  {
173
                    chp++;
174
                    arg[len] = mi_parse_escape (&chp);
175
                  }
176
                else
177
                  arg[len] = *chp++;
178
                len++;
179
              }
180
            arg[len] = '\0';
181
            chp++;              /* that closing quote. */
182
            break;
183
          }
184
        default:
185
          {
186
            /* An unquoted string.  Accumulate all non blank
187
               characters into a buffer. */
188
            int len;
189
            char *start = chp;
190
 
191
            while (*chp != '\0' && !isspace (*chp))
192
              {
193
                chp++;
194
              }
195
            len = chp - start;
196
            arg = xmalloc ((len + 1) * sizeof (char));
197
            strncpy (arg, start, len);
198
            arg[len] = '\0';
199
            break;
200
          }
201
        }
202
      /* Append arg to argv. */
203
      argv = xrealloc (argv, (argc + 2) * sizeof (char *));
204
      argv[argc++] = arg;
205
      argv[argc] = NULL;
206
    }
207
}
208
 
209
 
210
void
211
mi_parse_free (struct mi_parse *parse)
212
{
213
  if (parse == NULL)
214
    return;
215
  if (parse->command != NULL)
216
    xfree (parse->command);
217
  if (parse->token != NULL)
218
    xfree (parse->token);
219
  if (parse->args != NULL)
220
    xfree (parse->args);
221
  if (parse->argv != NULL)
222
    freeargv (parse->argv);
223
  xfree (parse);
224
}
225
 
226
 
227
struct mi_parse *
228
mi_parse (char *cmd)
229
{
230
  char *chp;
231
  struct mi_parse *parse = XMALLOC (struct mi_parse);
232
 
233
  memset (parse, 0, sizeof (*parse));
234
  parse->all = 0;
235
  parse->thread_group = -1;
236
  parse->thread = -1;
237
  parse->frame = -1;
238
 
239
  /* Before starting, skip leading white space. */
240
  while (isspace (*cmd))
241
    cmd++;
242
 
243
  /* Find/skip any token and then extract it. */
244
  for (chp = cmd; *chp >= '0' && *chp <= '9'; chp++)
245
    ;
246
  parse->token = xmalloc ((chp - cmd + 1) * sizeof (char *));
247
  memcpy (parse->token, cmd, (chp - cmd));
248
  parse->token[chp - cmd] = '\0';
249
 
250
  /* This wasn't a real MI command.  Return it as a CLI_COMMAND. */
251
  if (*chp != '-')
252
    {
253
      while (isspace (*chp))
254
        chp++;
255
      parse->command = xstrdup (chp);
256
      parse->op = CLI_COMMAND;
257
      return parse;
258
    }
259
 
260
  /* Extract the command. */
261
  {
262
    char *tmp = chp + 1;        /* discard ``-'' */
263
 
264
    for (; *chp && !isspace (*chp); chp++)
265
      ;
266
    parse->command = xmalloc ((chp - tmp + 1) * sizeof (char *));
267
    memcpy (parse->command, tmp, chp - tmp);
268
    parse->command[chp - tmp] = '\0';
269
  }
270
 
271
  /* Find the command in the MI table. */
272
  parse->cmd = mi_lookup (parse->command);
273
  if (parse->cmd == NULL)
274
    {
275
      /* FIXME: This should be a function call. */
276
      fprintf_unfiltered
277
        (raw_stdout,
278
         "%s^error,msg=\"Undefined MI command: %s\"\n",
279
         parse->token, parse->command);
280
      mi_parse_free (parse);
281
      return NULL;
282
    }
283
 
284
  /* Skip white space following the command. */
285
  while (isspace (*chp))
286
    chp++;
287
 
288
  /* Parse the --thread and --frame options, if present.  At present,
289
     some important commands, like '-break-*' are implemented by forwarding
290
     to the CLI layer directly.  We want to parse --thread and --frame
291
     here, so as not to leave those option in the string that will be passed
292
     to CLI.  */
293
  for (;;)
294
    {
295
      char *start = chp;
296
      size_t as = sizeof ("--all ") - 1;
297
      size_t tgs = sizeof ("--thread-group ") - 1;
298
      size_t ts = sizeof ("--thread ") - 1;
299
      size_t fs = sizeof ("--frame ") - 1;
300
 
301
      if (strncmp (chp, "--all ", as) == 0)
302
        {
303
          parse->all = 1;
304
          chp += as;
305
        }
306
      /* See if --all is the last token in the input.  */
307
      if (strcmp (chp, "--all") == 0)
308
        {
309
          parse->all = 1;
310
          chp += strlen (chp);
311
        }
312
      if (strncmp (chp, "--thread-group ", tgs) == 0)
313
        {
314
          if (parse->thread_group != -1)
315
            error (_("Duplicate '--thread-group' option"));
316
          chp += tgs;
317
          if (*chp != 'i')
318
            error (_("Invalid thread group id"));
319
          chp += 1;
320
          parse->thread_group = strtol (chp, &chp, 10);
321
        }
322
      if (strncmp (chp, "--thread ", ts) == 0)
323
        {
324
          if (parse->thread != -1)
325
            error (_("Duplicate '--thread' option"));
326
          chp += ts;
327
          parse->thread = strtol (chp, &chp, 10);
328
        }
329
      else if (strncmp (chp, "--frame ", fs) == 0)
330
        {
331
          if (parse->frame != -1)
332
            error (_("Duplicate '--frame' option"));
333
          chp += fs;
334
          parse->frame = strtol (chp, &chp, 10);
335
        }
336
      else
337
        break;
338
 
339
      if (*chp != '\0' && !isspace (*chp))
340
        error (_("Invalid value for the '%s' option"),
341
               start[2] == 't' ? "--thread" : "--frame");
342
      while (isspace (*chp))
343
        chp++;
344
    }
345
 
346
  /* For new argv commands, attempt to return the parsed argument
347
     list. */
348
  if (parse->cmd->argv_func != NULL)
349
    {
350
      mi_parse_argv (chp, parse);
351
      if (parse->argv == NULL)
352
        {
353
          /* FIXME: This should be a function call. */
354
          fprintf_unfiltered
355
            (raw_stdout,
356
             "%s^error,msg=\"Problem parsing arguments: %s %s\"\n",
357
             parse->token, parse->command, chp);
358
          mi_parse_free (parse);
359
          return NULL;
360
        }
361
    }
362
 
363
  /* FIXME: DELETE THIS */
364
  /* For CLI commands, also return the remainder of the
365
     command line as a single string. */
366
  if (parse->cmd->cli.cmd != NULL)
367
    parse->args = xstrdup (chp);
368
 
369
  /* Fully parsed. */
370
  parse->op = MI_COMMAND;
371
  return parse;
372
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.