1 /* The IGEN simulator generator for GDB, the GNU Debugger.
3 Copyright 2002, 2007 Free Software Foundation, Inc.
5 Contributed by Andrew Cagney.
7 This file is part of GDB.
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
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place - Suite 330,
22 Boston, MA 02111-1307, USA. */
26 #include <sys/types.h>
45 typedef struct _open_table open_table;
63 current_line (open_table * file)
65 line_ref *entry = ZALLOC (line_ref);
66 *entry = file->pseudo_line;
71 new_table_entry (open_table * file, table_entry_type type)
74 entry = ZALLOC (table_entry);
75 entry->file = file->root;
76 entry->line = current_line (file);
82 set_nr_table_entry_fields (table_entry *entry, int nr_fields)
84 entry->field = NZALLOC (char *, nr_fields + 1);
85 entry->nr_fields = nr_fields;
90 table_push (table *root,
91 line_ref *line, table_include *includes, const char *file_name)
96 table_include *include = &dummy;
98 /* dummy up a search of this directory */
99 dummy.next = includes;
102 /* create a file descriptor */
103 file = ZALLOC (open_table);
110 file->parent = root->current;
111 root->current = file;
115 /* save the file name */
117 NZALLOC (char, strlen (include->dir) + strlen (file_name) + 2);
118 if (dup_name == NULL)
123 if (include->dir[0] != '\0')
125 strcat (dup_name, include->dir);
126 strcat (dup_name, "/");
128 strcat (dup_name, file_name);
129 file->real_line.file_name = dup_name;
130 file->pseudo_line.file_name = dup_name;
133 ff = fopen (dup_name, "rb");
136 /* zfree (dup_name); */
137 if (include->next == NULL)
140 error (line, "Problem opening file `%s'\n", file_name);
144 include = include->next;
148 /* determine the size */
149 fseek (ff, 0, SEEK_END);
150 file->size = ftell (ff);
151 fseek (ff, 0, SEEK_SET);
153 /* allocate this much memory */
154 file->buffer = (char *) zalloc (file->size + 1);
155 if (file->buffer == NULL)
160 file->pos = file->buffer;
163 if (fread (file->buffer, 1, file->size, ff) < file->size)
168 file->buffer[file->size] = '\0';
170 /* set the initial line numbering */
171 file->real_line.line_nr = 1; /* specifies current line */
172 file->pseudo_line.line_nr = 1; /* specifies current line */
179 table_open (const char *file_name)
183 /* create a file descriptor */
184 root = ZALLOC (table);
191 table_push (root, NULL, NULL, file_name);
196 skip_spaces (char *chp)
200 if (*chp == '\0' || *chp == '\n' || !isspace (*chp))
208 back_spaces (char *start, char *chp)
212 if (chp <= start || !isspace (chp[-1]))
219 skip_digits (char *chp)
223 if (*chp == '\0' || *chp == '\n' || !isdigit (*chp))
230 skip_to_separator (char *chp, char *separators)
234 char *sep = separators;
248 skip_to_null (char *chp)
250 return skip_to_separator (chp, "");
255 skip_to_nl (char *chp)
257 return skip_to_separator (chp, "\n");
262 next_line (open_table * file)
264 file->pos = skip_to_nl (file->pos);
265 if (*file->pos == '0')
266 error (&file->pseudo_line, "Missing <nl> at end of line\n");
269 file->real_line.line_nr += 1;
270 file->pseudo_line.line_nr += 1;
275 table_read (table *root)
277 open_table *file = root->current;
278 table_entry *entry = NULL;
283 while (*file->pos == '\0')
285 if (file->parent != NULL)
288 root->current = file;
295 if (*file->pos == '{')
298 next_line (file); /* discard leading brace */
299 entry = new_table_entry (file, table_code_entry);
301 /* determine how many lines are involved - look for <nl> "}" */
304 while (*file->pos != '}')
309 set_nr_table_entry_fields (entry, nr_lines);
311 /* now enter each line */
314 for (line_nr = 0; line_nr < entry->nr_fields; line_nr++)
316 if (strncmp (chp, " ", 2) == 0)
317 entry->field[line_nr] = chp + 2;
319 entry->field[line_nr] = chp;
320 chp = skip_to_null (chp) + 1;
322 /* skip trailing brace */
323 ASSERT (*file->pos == '}');
330 if (*file->pos == '\t')
332 char *chp = file->pos;
333 entry = new_table_entry (file, table_code_entry);
334 /* determine how many lines are involved - look for <nl> !<tab> */
337 int nr_blank_lines = 0;
340 if (*file->pos == '\t')
342 nr_lines = nr_lines + nr_blank_lines + 1;
348 file->pos = skip_spaces (file->pos);
349 if (*file->pos != '\n')
355 set_nr_table_entry_fields (entry, nr_lines);
357 /* now enter each line */
360 for (line_nr = 0; line_nr < entry->nr_fields; line_nr++)
363 entry->field[line_nr] = chp + 1;
365 entry->field[line_nr] = ""; /* blank */
366 chp = skip_to_null (chp) + 1;
373 if (file->pos[0] == '#')
375 char *chp = skip_spaces (file->pos + 1);
377 /* cpp line-nr directive - # <line-nr> "<file>" */
379 && *skip_digits (chp) == ' '
380 && *skip_spaces (skip_digits (chp)) == '"')
385 /* parse the number */
386 line_nr = atoi (file->pos) - 1;
387 /* skip to the file name */
388 while (file->pos[0] != '0'
389 && file->pos[0] != '"' && file->pos[0] != '\0')
391 if (file->pos[0] != '"')
392 error (&file->real_line,
393 "Missing opening quote in cpp directive\n");
394 /* parse the file name */
396 file_name = file->pos;
397 while (file->pos[0] != '"' && file->pos[0] != '\0')
399 if (file->pos[0] != '"')
400 error (&file->real_line,
401 "Missing closing quote in cpp directive\n");
404 file->pos = skip_to_nl (file->pos);
405 if (file->pos[0] != '\n')
406 error (&file->real_line,
407 "Missing newline in cpp directive\n");
408 file->pseudo_line.file_name = file_name;
409 file->pseudo_line.line_nr = line_nr;
414 /* #define and #undef - not implemented yet */
416 /* Old style # comment */
421 /* blank line or end-of-file? */
422 file->pos = skip_spaces (file->pos);
423 if (*file->pos == '\0')
424 error (&file->pseudo_line, "Missing <nl> at end of file\n");
425 if (*file->pos == '\n')
431 /* comment - leading // or # - skip */
432 if ((file->pos[0] == '/' && file->pos[1] == '/')
433 || (file->pos[0] == '#'))
441 char *chp = file->pos;
442 entry = new_table_entry (file, table_colon_entry);
444 /* figure out how many fields */
450 tmpch = skip_to_separator (tmpch, "\\:");
453 /* eat the escaped character */
455 while (cp[1] != '\0')
463 else if (*tmpch != ':')
472 set_nr_table_entry_fields (entry, nr_fields);
477 for (field_nr = 0; field_nr < entry->nr_fields; field_nr++)
479 chp = skip_spaces (chp);
480 entry->field[field_nr] = chp;
481 chp = skip_to_null (chp);
482 *back_spaces (entry->field[field_nr], chp) = '\0';
491 ASSERT (entry == NULL || entry->field[entry->nr_fields] == NULL);
496 table_print_code (lf *file, table_entry *entry)
500 for (field_nr = 0; field_nr < entry->nr_fields; field_nr++)
502 char *chp = entry->field[field_nr];
503 int in_bit_field = 0;
505 lf_indent_suppress (file);
508 if (chp[0] == '{' && !isspace (chp[1]) && chp[1] != '\0')
511 nr += lf_putchr (file, '_');
513 else if (in_bit_field && chp[0] == ':')
515 nr += lf_putchr (file, '_');
517 else if (in_bit_field && *chp == '}')
519 nr += lf_putchr (file, '_');
524 nr += lf_putchr (file, *chp);
530 line_ref line = *entry->line;
531 line.line_nr += field_nr;
532 error (&line, "Bit field brace miss match\n");
534 nr += lf_putchr (file, '\n');
541 dump_line_ref (lf *file, char *prefix, const line_ref *line, char *suffix)
543 lf_printf (file, "%s(line_ref*) 0x%lx", prefix, (long) line);
546 lf_indent (file, +1);
547 lf_printf (file, "\n(line_nr %d)", line->line_nr);
548 lf_printf (file, "\n(file_name %s)", line->file_name);
549 lf_indent (file, -1);
551 lf_printf (file, "%s", suffix);
556 table_entry_type_to_str (table_entry_type type)
560 case table_code_entry:
562 case table_colon_entry:
563 return "colon-entry";
569 dump_table_entry (lf *file,
570 char *prefix, const table_entry *entry, char *suffix)
572 lf_printf (file, "%s(table_entry*) 0x%lx", prefix, (long) entry);
576 lf_indent (file, +1);
577 dump_line_ref (file, "\n(line ", entry->line, ")");
578 lf_printf (file, "\n(type %s)", table_entry_type_to_str (entry->type));
579 lf_printf (file, "\n(nr_fields %d)", entry->nr_fields);
580 lf_printf (file, "\n(fields");
581 lf_indent (file, +1);
582 for (field = 0; field < entry->nr_fields; field++)
583 lf_printf (file, "\n\"%s\"", entry->field[field]);
584 lf_indent (file, -1);
585 lf_printf (file, ")");
586 lf_indent (file, -1);
588 lf_printf (file, "%s", suffix);
594 main (int argc, char **argv)
603 printf ("Usage: table <file>\n");
607 t = table_open (argv[1]);
608 l = lf_open ("-", "stdout", lf_omit_references, lf_is_text, "tmp-table");
614 entry = table_read (t);
616 sprintf (line, "(%d ", line_nr);
617 dump_table_entry (l, line, entry, ")\n");
619 while (entry != NULL);