]>
git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - sim/igen/table.c
1 /* This file is part of the program psim.
3 Copyright (C) 1994-1995,1997 Andrew Cagney <cagney@highland.com.au>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 #include <sys/types.h>
41 typedef struct _open_table open_table
;
57 current_line (open_table
*file
)
59 line_ref
*entry
= ZALLOC (line_ref
);
60 *entry
= file
->pseudo_line
;
65 new_table_entry (open_table
*file
,
66 table_entry_type type
)
69 entry
= ZALLOC (table_entry
);
70 entry
->file
= file
->root
;
71 entry
->line
= current_line (file
);
77 set_nr_table_entry_fields (table_entry
*entry
,
80 entry
->field
= NZALLOC (char*, nr_fields
+ 1);
81 entry
->nr_fields
= nr_fields
;
86 table_push (table
*root
,
88 table_include
*includes
,
89 const char *file_name
)
94 table_include
*include
= &dummy
;
96 /* dummy up a search of this directory */
97 dummy
.next
= includes
;
100 /* create a file descriptor */
101 file
= ZALLOC (open_table
);
108 file
->parent
= root
->current
;
109 root
->current
= file
;
113 /* save the file name */
114 char *dup_name
= NZALLOC (char, strlen (include
->dir
) + strlen (file_name
) + 2);
115 if (dup_name
== NULL
)
120 if (include
->dir
[0] != '\0')
122 strcat (dup_name
, include
->dir
);
123 strcat (dup_name
, "/");
125 strcat (dup_name
, file_name
);
126 file
->real_line
.file_name
= dup_name
;
127 file
->pseudo_line
.file_name
= dup_name
;
130 ff
= fopen (dup_name
, "rb");
133 /* zfree (dup_name); */
134 if (include
->next
== NULL
)
137 error (line
, "Problem opening file `%s'\n", file_name
);
141 include
= include
->next
;
145 /* determine the size */
146 fseek (ff
, 0, SEEK_END
);
147 file
->size
= ftell (ff
);
148 fseek (ff
, 0, SEEK_SET
);
150 /* allocate this much memory */
151 file
->buffer
= (char*) zalloc (file
->size
+ 1);
152 if (file
->buffer
== NULL
)
157 file
->pos
= file
->buffer
;
160 if (fread (file
->buffer
, 1, file
->size
, ff
) < file
->size
) {
164 file
->buffer
[file
->size
] = '\0';
166 /* set the initial line numbering */
167 file
->real_line
.line_nr
= 1; /* specifies current line */
168 file
->pseudo_line
.line_nr
= 1; /* specifies current line */
175 table_open (const char *file_name
)
179 /* create a file descriptor */
180 root
= ZALLOC (table
);
187 table_push (root
, NULL
, NULL
, file_name
);
192 skip_spaces (char *chp
)
206 back_spaces (char *start
, char *chp
)
211 || !isspace (chp
[-1]))
218 skip_digits (char *chp
)
231 skip_to_separator (char *chp
,
236 char *sep
= separators
;
250 skip_to_null (char *chp
)
252 return skip_to_separator (chp
, "");
257 skip_to_nl (char * chp
)
259 return skip_to_separator (chp
, "\n");
264 next_line (open_table
*file
)
266 file
->pos
= skip_to_nl (file
->pos
);
267 if (*file
->pos
== '0')
268 error (&file
->pseudo_line
, "Missing <nl> at end of line\n");
271 file
->real_line
.line_nr
+= 1;
272 file
->pseudo_line
.line_nr
+= 1;
277 table_read (table
*root
)
279 open_table
*file
= root
->current
;
280 table_entry
*entry
= NULL
;
285 while (*file
->pos
== '\0')
287 if (file
->parent
!= NULL
)
290 root
->current
= file
;
297 if (*file
->pos
== '{')
300 next_line (file
); /* discard leading brace */
301 entry
= new_table_entry (file
, table_code_entry
);
303 /* determine how many lines are involved - look for <nl> "}" */
306 while (*file
->pos
!= '}')
311 set_nr_table_entry_fields (entry
, nr_lines
);
313 /* now enter each line */
316 for (line_nr
= 0; line_nr
< entry
->nr_fields
; line_nr
++)
318 if (strncmp (chp
, " ", 2) == 0)
319 entry
->field
[line_nr
] = chp
+ 2;
321 entry
->field
[line_nr
] = chp
;
322 chp
= skip_to_null (chp
) + 1;
324 /* skip trailing brace */
325 ASSERT (*file
->pos
== '}');
332 if (*file
->pos
== '\t')
334 char *chp
= file
->pos
;
335 entry
= new_table_entry (file
, table_code_entry
);
336 /* determine how many lines are involved - look for <nl> !<tab> */
339 int nr_blank_lines
= 0;
342 if (*file
->pos
== '\t')
344 nr_lines
= nr_lines
+ nr_blank_lines
+ 1;
350 file
->pos
= skip_spaces (file
->pos
);
351 if (*file
->pos
!= '\n')
357 set_nr_table_entry_fields (entry
, nr_lines
);
359 /* now enter each line */
362 for (line_nr
= 0; line_nr
< entry
->nr_fields
; line_nr
++)
365 entry
->field
[line_nr
] = chp
+ 1;
367 entry
->field
[line_nr
] = ""; /* blank */
368 chp
= skip_to_null (chp
) + 1;
375 if (file
->pos
[0] == '#')
377 char *chp
= skip_spaces (file
->pos
+ 1);
379 /* cpp line-nr directive - # <line-nr> "<file>" */
381 && *skip_digits (chp
) == ' '
382 && *skip_spaces (skip_digits (chp
)) == '"')
387 /* parse the number */
388 line_nr
= atoi(file
->pos
) - 1;
389 /* skip to the file name */
390 while (file
->pos
[0] != '0'
391 && file
->pos
[0] != '"'
392 && file
->pos
[0] != '\0')
394 if (file
->pos
[0] != '"')
395 error (&file
->real_line
, "Missing opening quote in cpp directive\n");
396 /* parse the file name */
398 file_name
= file
->pos
;
399 while (file
->pos
[0] != '"'
400 && file
->pos
[0] != '\0')
402 if (file
->pos
[0] != '"')
403 error (&file
->real_line
, "Missing closing quote in cpp directive\n");
406 file
->pos
= skip_to_nl (file
->pos
);
407 if (file
->pos
[0] != '\n')
408 error (&file
->real_line
, "Missing newline in cpp directive\n");
409 file
->pseudo_line
.file_name
= file_name
;
410 file
->pseudo_line
.line_nr
= line_nr
;
415 /* #define and #undef - not implemented yet */
417 /* Old style # comment */
422 /* blank line or end-of-file? */
423 file
->pos
= skip_spaces (file
->pos
);
424 if (*file
->pos
== '\0')
425 error (&file
->pseudo_line
, "Missing <nl> at end of file\n");
426 if (*file
->pos
== '\n')
432 /* comment - leading // or # - skip */
433 if ((file
->pos
[0] == '/' && file
->pos
[1] == '/')
434 || (file
->pos
[0] == '#'))
442 char *chp
= file
->pos
;
443 entry
= new_table_entry (file
, table_colon_entry
);
445 /* figure out how many fields */
451 tmpch
= skip_to_separator (tmpch
, "\\:");
454 /* eat the escaped character */
456 while (cp
[1] != '\0')
464 else if (*tmpch
!= ':')
473 set_nr_table_entry_fields (entry
, nr_fields
);
478 for (field_nr
= 0; field_nr
< entry
->nr_fields
; field_nr
++)
480 chp
= skip_spaces (chp
);
481 entry
->field
[field_nr
] = chp
;
482 chp
= skip_to_null (chp
);
483 *back_spaces (entry
->field
[field_nr
], chp
) = '\0';
492 ASSERT (entry
== NULL
|| entry
->field
[entry
->nr_fields
] == NULL
);
497 table_print_code (lf
*file
,
503 field_nr
< entry
->nr_fields
;
506 char *chp
= entry
->field
[field_nr
];
507 int in_bit_field
= 0;
509 lf_indent_suppress(file
);
517 nr
+= lf_putchr(file
, '_');
519 else if (in_bit_field
&& chp
[0] == ':')
521 nr
+= lf_putchr(file
, '_');
523 else if (in_bit_field
&& *chp
== '}')
525 nr
+= lf_putchr(file
, '_');
530 nr
+= lf_putchr(file
, *chp
);
536 line_ref line
= *entry
->line
;
537 line
.line_nr
+= field_nr
;
538 error (&line
, "Bit field brace miss match\n");
540 nr
+= lf_putchr(file
, '\n');
547 dump_line_ref (lf
*file
,
549 const line_ref
*line
,
552 lf_printf (file
, "%s(line_ref*) 0x%lx", prefix
, (long) line
);
555 lf_indent (file
, +1);
556 lf_printf (file
, "\n(line_nr %d)", line
->line_nr
);
557 lf_printf (file
, "\n(file_name %s)", line
->file_name
);
558 lf_indent (file
, -1);
560 lf_printf (file
, "%s", suffix
);
565 table_entry_type_to_str (table_entry_type type
)
569 case table_code_entry
: return "code-entry";
570 case table_colon_entry
: return "colon-entry";
576 dump_table_entry(lf
*file
,
578 const table_entry
*entry
,
581 lf_printf (file
, "%s(table_entry*) 0x%lx", prefix
, (long) entry
);
585 lf_indent (file
, +1);
586 dump_line_ref (file
, "\n(line ", entry
->line
, ")");
587 lf_printf (file
, "\n(type %s)", table_entry_type_to_str (entry
->type
));
588 lf_printf (file
, "\n(nr_fields %d)", entry
->nr_fields
);
589 lf_printf (file
, "\n(fields");
590 lf_indent (file
, +1);
591 for (field
= 0; field
< entry
->nr_fields
; field
++)
592 lf_printf (file
, "\n\"%s\"", entry
->field
[field
]);
593 lf_indent (file
, -1);
594 lf_printf (file
, ")");
595 lf_indent (file
, -1);
597 lf_printf (file
, "%s", suffix
);
603 main(int argc
, char **argv
)
612 printf("Usage: table <file>\n");
616 t
= table_open (argv
[1]);
617 l
= lf_open ("-", "stdout", lf_omit_references
, lf_is_text
, "tmp-table");
623 entry
= table_read (t
);
625 sprintf (line
, "(%d ", line_nr
);
626 dump_table_entry (l
, line
, entry
, ")\n");
628 while (entry
!= NULL
);