1 /* The IGEN simulator generator for GDB, the GNU Debugger.
3 Copyright 2002-2022 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 3 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, see <http://www.gnu.org/licenses/>. */
24 #include <sys/types.h>
37 typedef struct _open_table open_table
;
55 current_line (open_table
* file
)
57 line_ref
*entry
= ZALLOC (line_ref
);
58 *entry
= file
->pseudo_line
;
63 new_table_entry (open_table
* file
, table_entry_type type
)
66 entry
= ZALLOC (table_entry
);
67 entry
->file
= file
->root
;
68 entry
->line
= current_line (file
);
74 set_nr_table_entry_fields (table_entry
*entry
, int nr_fields
)
76 entry
->field
= NZALLOC (char *, nr_fields
+ 1);
77 entry
->nr_fields
= nr_fields
;
82 table_push (table
*root
,
83 line_ref
*line
, table_include
*includes
, const char *file_name
)
88 table_include
*include
= &dummy
;
90 /* dummy up a search of this directory */
91 dummy
.next
= includes
;
94 /* create a file descriptor */
95 file
= ZALLOC (open_table
);
102 file
->parent
= root
->current
;
103 root
->current
= file
;
107 /* save the file name */
109 NZALLOC (char, strlen (include
->dir
) + strlen (file_name
) + 2);
110 if (dup_name
== NULL
)
115 if (include
->dir
[0] != '\0')
117 strcat (dup_name
, include
->dir
);
118 strcat (dup_name
, "/");
120 strcat (dup_name
, file_name
);
121 file
->real_line
.file_name
= dup_name
;
122 file
->pseudo_line
.file_name
= dup_name
;
125 ff
= fopen (dup_name
, "rb");
128 /* free (dup_name); */
129 if (include
->next
== NULL
)
132 error (line
, "Problem opening file `%s'\n", file_name
);
136 include
= include
->next
;
140 /* determine the size */
141 fseek (ff
, 0, SEEK_END
);
142 file
->size
= ftell (ff
);
143 fseek (ff
, 0, SEEK_SET
);
145 /* allocate this much memory */
146 file
->buffer
= (char *) zalloc (file
->size
+ 1);
147 if (file
->buffer
== NULL
)
152 file
->pos
= file
->buffer
;
155 if (fread (file
->buffer
, 1, file
->size
, ff
) < file
->size
)
160 file
->buffer
[file
->size
] = '\0';
162 /* set the initial line numbering */
163 file
->real_line
.line_nr
= 1; /* specifies current line */
164 file
->pseudo_line
.line_nr
= 1; /* specifies current line */
171 table_open (const char *file_name
)
175 /* create a file descriptor */
176 root
= ZALLOC (table
);
183 table_push (root
, NULL
, NULL
, file_name
);
188 skip_spaces (char *chp
)
192 if (*chp
== '\0' || *chp
== '\n' || !isspace (*chp
))
200 back_spaces (char *start
, char *chp
)
204 if (chp
<= start
|| !isspace (chp
[-1]))
211 skip_digits (char *chp
)
215 if (*chp
== '\0' || *chp
== '\n' || !isdigit (*chp
))
222 skip_to_separator (char *chp
, char *separators
)
226 char *sep
= separators
;
240 skip_to_null (char *chp
)
242 return skip_to_separator (chp
, "");
247 skip_to_nl (char *chp
)
249 return skip_to_separator (chp
, "\n");
254 next_line (open_table
* file
)
256 file
->pos
= skip_to_nl (file
->pos
);
257 if (*file
->pos
== '0')
258 error (&file
->pseudo_line
, "Missing <nl> at end of line\n");
261 file
->real_line
.line_nr
+= 1;
262 file
->pseudo_line
.line_nr
+= 1;
267 table_read (table
*root
)
269 open_table
*file
= root
->current
;
270 table_entry
*entry
= NULL
;
275 while (*file
->pos
== '\0')
277 if (file
->parent
!= NULL
)
280 root
->current
= file
;
287 if (*file
->pos
== '{')
290 next_line (file
); /* discard leading brace */
291 entry
= new_table_entry (file
, table_code_entry
);
293 /* determine how many lines are involved - look for <nl> "}" */
296 while (*file
->pos
!= '}')
301 set_nr_table_entry_fields (entry
, nr_lines
);
303 /* now enter each line */
306 for (line_nr
= 0; line_nr
< entry
->nr_fields
; line_nr
++)
308 if (strncmp (chp
, " ", 2) == 0)
309 entry
->field
[line_nr
] = chp
+ 2;
311 entry
->field
[line_nr
] = chp
;
312 chp
= skip_to_null (chp
) + 1;
314 /* skip trailing brace */
315 ASSERT (*file
->pos
== '}');
322 if (*file
->pos
== '\t')
324 char *chp
= file
->pos
;
325 entry
= new_table_entry (file
, table_code_entry
);
326 /* determine how many lines are involved - look for <nl> !<tab> */
329 int nr_blank_lines
= 0;
332 if (*file
->pos
== '\t')
334 nr_lines
= nr_lines
+ nr_blank_lines
+ 1;
340 file
->pos
= skip_spaces (file
->pos
);
341 if (*file
->pos
!= '\n')
347 set_nr_table_entry_fields (entry
, nr_lines
);
349 /* now enter each line */
352 for (line_nr
= 0; line_nr
< entry
->nr_fields
; line_nr
++)
355 entry
->field
[line_nr
] = chp
+ 1;
357 entry
->field
[line_nr
] = ""; /* blank */
358 chp
= skip_to_null (chp
) + 1;
365 if (file
->pos
[0] == '#')
367 char *chp
= skip_spaces (file
->pos
+ 1);
369 /* cpp line-nr directive - # <line-nr> "<file>" */
371 && *skip_digits (chp
) == ' '
372 && *skip_spaces (skip_digits (chp
)) == '"')
377 /* parse the number */
378 line_nr
= atoi (file
->pos
) - 1;
379 /* skip to the file name */
380 while (file
->pos
[0] != '0'
381 && file
->pos
[0] != '"' && file
->pos
[0] != '\0')
383 if (file
->pos
[0] != '"')
384 error (&file
->real_line
,
385 "Missing opening quote in cpp directive\n");
386 /* parse the file name */
388 file_name
= file
->pos
;
389 while (file
->pos
[0] != '"' && file
->pos
[0] != '\0')
391 if (file
->pos
[0] != '"')
392 error (&file
->real_line
,
393 "Missing closing quote in cpp directive\n");
396 file
->pos
= skip_to_nl (file
->pos
);
397 if (file
->pos
[0] != '\n')
398 error (&file
->real_line
,
399 "Missing newline in cpp directive\n");
400 file
->pseudo_line
.file_name
= file_name
;
401 file
->pseudo_line
.line_nr
= line_nr
;
406 /* #define and #undef - not implemented yet */
408 /* Old style # comment */
413 /* blank line or end-of-file? */
414 file
->pos
= skip_spaces (file
->pos
);
415 if (*file
->pos
== '\0')
416 error (&file
->pseudo_line
, "Missing <nl> at end of file\n");
417 if (*file
->pos
== '\n')
423 /* comment - leading // or # - skip */
424 if ((file
->pos
[0] == '/' && file
->pos
[1] == '/')
425 || (file
->pos
[0] == '#'))
433 char *chp
= file
->pos
;
434 entry
= new_table_entry (file
, table_colon_entry
);
436 /* figure out how many fields */
442 tmpch
= skip_to_separator (tmpch
, "\\:");
445 /* eat the escaped character */
447 while (cp
[1] != '\0')
455 else if (*tmpch
!= ':')
464 set_nr_table_entry_fields (entry
, nr_fields
);
469 for (field_nr
= 0; field_nr
< entry
->nr_fields
; field_nr
++)
471 chp
= skip_spaces (chp
);
472 entry
->field
[field_nr
] = chp
;
473 chp
= skip_to_null (chp
);
474 *back_spaces (entry
->field
[field_nr
], chp
) = '\0';
483 ASSERT (entry
== NULL
|| entry
->field
[entry
->nr_fields
] == NULL
);
488 table_print_code (lf
*file
, table_entry
*entry
)
492 for (field_nr
= 0; field_nr
< entry
->nr_fields
; field_nr
++)
494 char *chp
= entry
->field
[field_nr
];
495 int in_bit_field
= 0;
497 lf_indent_suppress (file
);
500 if (chp
[0] == '{' && !isspace (chp
[1]) && chp
[1] != '\0')
503 nr
+= lf_putchr (file
, '_');
505 else if (in_bit_field
&& chp
[0] == ':')
507 nr
+= lf_putchr (file
, '_');
509 else if (in_bit_field
&& *chp
== '}')
511 nr
+= lf_putchr (file
, '_');
516 nr
+= lf_putchr (file
, *chp
);
522 line_ref line
= *entry
->line
;
523 line
.line_nr
+= field_nr
;
524 error (&line
, "Bit field brace miss match\n");
526 nr
+= lf_putchr (file
, '\n');
533 dump_line_ref (lf
*file
, char *prefix
, const line_ref
*line
, char *suffix
)
535 lf_printf (file
, "%s(line_ref*) 0x%lx", prefix
, (long) line
);
538 lf_indent (file
, +1);
539 lf_printf (file
, "\n(line_nr %d)", line
->line_nr
);
540 lf_printf (file
, "\n(file_name %s)", line
->file_name
);
541 lf_indent (file
, -1);
543 lf_printf (file
, "%s", suffix
);
548 table_entry_type_to_str (table_entry_type type
)
552 case table_code_entry
:
554 case table_colon_entry
:
555 return "colon-entry";
561 dump_table_entry (lf
*file
,
562 char *prefix
, const table_entry
*entry
, char *suffix
)
564 lf_printf (file
, "%s(table_entry*) 0x%lx", prefix
, (long) entry
);
568 lf_indent (file
, +1);
569 dump_line_ref (file
, "\n(line ", entry
->line
, ")");
570 lf_printf (file
, "\n(type %s)", table_entry_type_to_str (entry
->type
));
571 lf_printf (file
, "\n(nr_fields %d)", entry
->nr_fields
);
572 lf_printf (file
, "\n(fields");
573 lf_indent (file
, +1);
574 for (field
= 0; field
< entry
->nr_fields
; field
++)
575 lf_printf (file
, "\n\"%s\"", entry
->field
[field
]);
576 lf_indent (file
, -1);
577 lf_printf (file
, ")");
578 lf_indent (file
, -1);
580 lf_printf (file
, "%s", suffix
);
586 main (int argc
, char **argv
)
595 printf ("Usage: table <file>\n");
599 t
= table_open (argv
[1]);
600 l
= lf_open ("-", "stdout", lf_omit_references
, lf_is_text
, "tmp-table");
606 entry
= table_read (t
);
608 sprintf (line
, "(%d ", line_nr
);
609 dump_table_entry (l
, line
, entry
, ")\n");
611 while (entry
!= NULL
);
This page took 0.041467 seconds and 4 git commands to generate.