14e98e3e1Schristos /* The IGEN simulator generator for GDB, the GNU Debugger. 24e98e3e1Schristos 3*71f62182Schristos Copyright 2002-2024 Free Software Foundation, Inc. 44e98e3e1Schristos 54e98e3e1Schristos Contributed by Andrew Cagney. 64e98e3e1Schristos 74e98e3e1Schristos This file is part of GDB. 84e98e3e1Schristos 94e98e3e1Schristos This program is free software; you can redistribute it and/or modify 104e98e3e1Schristos it under the terms of the GNU General Public License as published by 114e98e3e1Schristos the Free Software Foundation; either version 3 of the License, or 124e98e3e1Schristos (at your option) any later version. 134e98e3e1Schristos 144e98e3e1Schristos This program is distributed in the hope that it will be useful, 154e98e3e1Schristos but WITHOUT ANY WARRANTY; without even the implied warranty of 164e98e3e1Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 174e98e3e1Schristos GNU General Public License for more details. 184e98e3e1Schristos 194e98e3e1Schristos You should have received a copy of the GNU General Public License 204e98e3e1Schristos along with this program. If not, see <http://www.gnu.org/licenses/>. */ 214e98e3e1Schristos 224e98e3e1Schristos 234e98e3e1Schristos 244e98e3e1Schristos #include <sys/types.h> 254e98e3e1Schristos #include <sys/stat.h> 264e98e3e1Schristos #include <stdio.h> 274e98e3e1Schristos #include <fcntl.h> 284e98e3e1Schristos #include <ctype.h> 294e98e3e1Schristos 304e98e3e1Schristos #include "misc.h" 314e98e3e1Schristos #include "lf.h" 324e98e3e1Schristos #include "table.h" 334e98e3e1Schristos 344e98e3e1Schristos #include <unistd.h> 354e98e3e1Schristos #include <stdlib.h> 364e98e3e1Schristos 374e98e3e1Schristos typedef struct _open_table open_table; 384e98e3e1Schristos struct _open_table 394e98e3e1Schristos { 404e98e3e1Schristos size_t size; 414e98e3e1Schristos char *buffer; 424e98e3e1Schristos char *pos; 434e98e3e1Schristos line_ref pseudo_line; 444e98e3e1Schristos line_ref real_line; 454e98e3e1Schristos open_table *parent; 464e98e3e1Schristos table *root; 474e98e3e1Schristos }; 484e98e3e1Schristos struct _table 494e98e3e1Schristos { 504e98e3e1Schristos open_table *current; 514e98e3e1Schristos }; 524e98e3e1Schristos 534e98e3e1Schristos 544e98e3e1Schristos static line_ref * 554e98e3e1Schristos current_line (open_table * file) 564e98e3e1Schristos { 574e98e3e1Schristos line_ref *entry = ZALLOC (line_ref); 584e98e3e1Schristos *entry = file->pseudo_line; 594e98e3e1Schristos return entry; 604e98e3e1Schristos } 614e98e3e1Schristos 624e98e3e1Schristos static table_entry * 634e98e3e1Schristos new_table_entry (open_table * file, table_entry_type type) 644e98e3e1Schristos { 654e98e3e1Schristos table_entry *entry; 664e98e3e1Schristos entry = ZALLOC (table_entry); 674e98e3e1Schristos entry->file = file->root; 684e98e3e1Schristos entry->line = current_line (file); 694e98e3e1Schristos entry->type = type; 704e98e3e1Schristos return entry; 714e98e3e1Schristos } 724e98e3e1Schristos 734e98e3e1Schristos static void 744e98e3e1Schristos set_nr_table_entry_fields (table_entry *entry, int nr_fields) 754e98e3e1Schristos { 764e98e3e1Schristos entry->field = NZALLOC (char *, nr_fields + 1); 774e98e3e1Schristos entry->nr_fields = nr_fields; 784e98e3e1Schristos } 794e98e3e1Schristos 804e98e3e1Schristos 814e98e3e1Schristos void 824e98e3e1Schristos table_push (table *root, 834b169a6bSchristos const line_ref *line, 844b169a6bSchristos table_include *includes, 854b169a6bSchristos const char *file_name) 864e98e3e1Schristos { 874e98e3e1Schristos FILE *ff; 884e98e3e1Schristos open_table *file; 894e98e3e1Schristos table_include dummy; 904e98e3e1Schristos table_include *include = &dummy; 914e98e3e1Schristos 924e98e3e1Schristos /* dummy up a search of this directory */ 934e98e3e1Schristos dummy.next = includes; 944e98e3e1Schristos dummy.dir = ""; 954e98e3e1Schristos 964e98e3e1Schristos /* create a file descriptor */ 974e98e3e1Schristos file = ZALLOC (open_table); 984e98e3e1Schristos if (file == NULL) 994e98e3e1Schristos { 1004e98e3e1Schristos perror (file_name); 1014e98e3e1Schristos exit (1); 1024e98e3e1Schristos } 1034e98e3e1Schristos file->root = root; 1044e98e3e1Schristos file->parent = root->current; 1054e98e3e1Schristos root->current = file; 1064e98e3e1Schristos 1074e98e3e1Schristos while (1) 1084e98e3e1Schristos { 1094e98e3e1Schristos /* save the file name */ 1104e98e3e1Schristos char *dup_name = 1114e98e3e1Schristos NZALLOC (char, strlen (include->dir) + strlen (file_name) + 2); 1124e98e3e1Schristos if (dup_name == NULL) 1134e98e3e1Schristos { 1144e98e3e1Schristos perror (file_name); 1154e98e3e1Schristos exit (1); 1164e98e3e1Schristos } 1174e98e3e1Schristos if (include->dir[0] != '\0') 1184e98e3e1Schristos { 1194e98e3e1Schristos strcat (dup_name, include->dir); 1204e98e3e1Schristos strcat (dup_name, "/"); 1214e98e3e1Schristos } 1224e98e3e1Schristos strcat (dup_name, file_name); 1234e98e3e1Schristos file->real_line.file_name = dup_name; 1244e98e3e1Schristos file->pseudo_line.file_name = dup_name; 1254e98e3e1Schristos /* open the file */ 1264e98e3e1Schristos 1274e98e3e1Schristos ff = fopen (dup_name, "rb"); 1284e98e3e1Schristos if (ff) 1294e98e3e1Schristos break; 1304e98e3e1Schristos /* free (dup_name); */ 1314e98e3e1Schristos if (include->next == NULL) 1324e98e3e1Schristos { 1334e98e3e1Schristos if (line != NULL) 1344e98e3e1Schristos error (line, "Problem opening file `%s'\n", file_name); 1354e98e3e1Schristos perror (file_name); 1364e98e3e1Schristos exit (1); 1374e98e3e1Schristos } 1384e98e3e1Schristos include = include->next; 1394e98e3e1Schristos } 1404e98e3e1Schristos 1414e98e3e1Schristos 1424e98e3e1Schristos /* determine the size */ 1434e98e3e1Schristos fseek (ff, 0, SEEK_END); 1444e98e3e1Schristos file->size = ftell (ff); 1454e98e3e1Schristos fseek (ff, 0, SEEK_SET); 1464e98e3e1Schristos 1474e98e3e1Schristos /* allocate this much memory */ 1484e98e3e1Schristos file->buffer = (char *) zalloc (file->size + 1); 1494e98e3e1Schristos if (file->buffer == NULL) 1504e98e3e1Schristos { 1514e98e3e1Schristos perror (file_name); 1524e98e3e1Schristos exit (1); 1534e98e3e1Schristos } 1544e98e3e1Schristos file->pos = file->buffer; 1554e98e3e1Schristos 1564e98e3e1Schristos /* read it all in */ 1574e98e3e1Schristos if (fread (file->buffer, 1, file->size, ff) < file->size) 1584e98e3e1Schristos { 1594e98e3e1Schristos perror (file_name); 1604e98e3e1Schristos exit (1); 1614e98e3e1Schristos } 1624e98e3e1Schristos file->buffer[file->size] = '\0'; 1634e98e3e1Schristos 1644e98e3e1Schristos /* set the initial line numbering */ 1654e98e3e1Schristos file->real_line.line_nr = 1; /* specifies current line */ 1664e98e3e1Schristos file->pseudo_line.line_nr = 1; /* specifies current line */ 1674e98e3e1Schristos 1684e98e3e1Schristos /* done */ 1694e98e3e1Schristos fclose (ff); 1704e98e3e1Schristos } 1714e98e3e1Schristos 1724e98e3e1Schristos table * 1734e98e3e1Schristos table_open (const char *file_name) 1744e98e3e1Schristos { 1754e98e3e1Schristos table *root; 1764e98e3e1Schristos 1774e98e3e1Schristos /* create a file descriptor */ 1784e98e3e1Schristos root = ZALLOC (table); 1794e98e3e1Schristos if (root == NULL) 1804e98e3e1Schristos { 1814e98e3e1Schristos perror (file_name); 1824e98e3e1Schristos exit (1); 1834e98e3e1Schristos } 1844e98e3e1Schristos 1854e98e3e1Schristos table_push (root, NULL, NULL, file_name); 1864e98e3e1Schristos return root; 1874e98e3e1Schristos } 1884e98e3e1Schristos 1894e98e3e1Schristos char * 1904e98e3e1Schristos skip_spaces (char *chp) 1914e98e3e1Schristos { 1924e98e3e1Schristos while (1) 1934e98e3e1Schristos { 1944e98e3e1Schristos if (*chp == '\0' || *chp == '\n' || !isspace (*chp)) 1954e98e3e1Schristos return chp; 1964e98e3e1Schristos chp++; 1974e98e3e1Schristos } 1984e98e3e1Schristos } 1994e98e3e1Schristos 2004e98e3e1Schristos 2014e98e3e1Schristos char * 2024e98e3e1Schristos back_spaces (char *start, char *chp) 2034e98e3e1Schristos { 2044e98e3e1Schristos while (1) 2054e98e3e1Schristos { 2064e98e3e1Schristos if (chp <= start || !isspace (chp[-1])) 2074e98e3e1Schristos return chp; 2084e98e3e1Schristos chp--; 2094e98e3e1Schristos } 2104e98e3e1Schristos } 2114e98e3e1Schristos 2124e98e3e1Schristos char * 2134e98e3e1Schristos skip_digits (char *chp) 2144e98e3e1Schristos { 2154e98e3e1Schristos while (1) 2164e98e3e1Schristos { 2174e98e3e1Schristos if (*chp == '\0' || *chp == '\n' || !isdigit (*chp)) 2184e98e3e1Schristos return chp; 2194e98e3e1Schristos chp++; 2204e98e3e1Schristos } 2214e98e3e1Schristos } 2224e98e3e1Schristos 2234e98e3e1Schristos char * 2244e98e3e1Schristos skip_to_separator (char *chp, char *separators) 2254e98e3e1Schristos { 2264e98e3e1Schristos while (1) 2274e98e3e1Schristos { 2284e98e3e1Schristos char *sep = separators; 2294e98e3e1Schristos while (1) 2304e98e3e1Schristos { 2314e98e3e1Schristos if (*chp == *sep) 2324e98e3e1Schristos return chp; 2334e98e3e1Schristos if (*sep == '\0') 2344e98e3e1Schristos break; 2354e98e3e1Schristos sep++; 2364e98e3e1Schristos } 2374e98e3e1Schristos chp++; 2384e98e3e1Schristos } 2394e98e3e1Schristos } 2404e98e3e1Schristos 2414e98e3e1Schristos static char * 2424e98e3e1Schristos skip_to_null (char *chp) 2434e98e3e1Schristos { 2444e98e3e1Schristos return skip_to_separator (chp, ""); 2454e98e3e1Schristos } 2464e98e3e1Schristos 2474e98e3e1Schristos 2484e98e3e1Schristos static char * 2494e98e3e1Schristos skip_to_nl (char *chp) 2504e98e3e1Schristos { 2514e98e3e1Schristos return skip_to_separator (chp, "\n"); 2524e98e3e1Schristos } 2534e98e3e1Schristos 2544e98e3e1Schristos 2554e98e3e1Schristos static void 2564e98e3e1Schristos next_line (open_table * file) 2574e98e3e1Schristos { 2584e98e3e1Schristos file->pos = skip_to_nl (file->pos); 2594e98e3e1Schristos if (*file->pos == '0') 2604e98e3e1Schristos error (&file->pseudo_line, "Missing <nl> at end of line\n"); 2614e98e3e1Schristos *file->pos = '\0'; 2624e98e3e1Schristos file->pos += 1; 2634e98e3e1Schristos file->real_line.line_nr += 1; 2644e98e3e1Schristos file->pseudo_line.line_nr += 1; 2654e98e3e1Schristos } 2664e98e3e1Schristos 2674e98e3e1Schristos 2684e98e3e1Schristos extern table_entry * 2694e98e3e1Schristos table_read (table *root) 2704e98e3e1Schristos { 2714e98e3e1Schristos open_table *file = root->current; 2724e98e3e1Schristos table_entry *entry = NULL; 2734e98e3e1Schristos while (1) 2744e98e3e1Schristos { 2754e98e3e1Schristos 2764e98e3e1Schristos /* end-of-file? */ 2774e98e3e1Schristos while (*file->pos == '\0') 2784e98e3e1Schristos { 2794e98e3e1Schristos if (file->parent != NULL) 2804e98e3e1Schristos { 2814e98e3e1Schristos file = file->parent; 2824e98e3e1Schristos root->current = file; 2834e98e3e1Schristos } 2844e98e3e1Schristos else 2854e98e3e1Schristos return NULL; 2864e98e3e1Schristos } 2874e98e3e1Schristos 2884e98e3e1Schristos /* code_block? */ 2894e98e3e1Schristos if (*file->pos == '{') 2904e98e3e1Schristos { 2914e98e3e1Schristos char *chp; 2924e98e3e1Schristos next_line (file); /* discard leading brace */ 2934e98e3e1Schristos entry = new_table_entry (file, table_code_entry); 2944e98e3e1Schristos chp = file->pos; 2954e98e3e1Schristos /* determine how many lines are involved - look for <nl> "}" */ 2964e98e3e1Schristos { 2974e98e3e1Schristos int nr_lines = 0; 2984e98e3e1Schristos while (*file->pos != '}') 2994e98e3e1Schristos { 3004e98e3e1Schristos next_line (file); 3014e98e3e1Schristos nr_lines++; 3024e98e3e1Schristos } 3034e98e3e1Schristos set_nr_table_entry_fields (entry, nr_lines); 3044e98e3e1Schristos } 3054e98e3e1Schristos /* now enter each line */ 3064e98e3e1Schristos { 3074e98e3e1Schristos int line_nr; 3084e98e3e1Schristos for (line_nr = 0; line_nr < entry->nr_fields; line_nr++) 3094e98e3e1Schristos { 3104e98e3e1Schristos if (strncmp (chp, " ", 2) == 0) 3114e98e3e1Schristos entry->field[line_nr] = chp + 2; 3124e98e3e1Schristos else 3134e98e3e1Schristos entry->field[line_nr] = chp; 3144e98e3e1Schristos chp = skip_to_null (chp) + 1; 3154e98e3e1Schristos } 3164e98e3e1Schristos /* skip trailing brace */ 3174e98e3e1Schristos ASSERT (*file->pos == '}'); 3184e98e3e1Schristos next_line (file); 3194e98e3e1Schristos } 3204e98e3e1Schristos break; 3214e98e3e1Schristos } 3224e98e3e1Schristos 3234e98e3e1Schristos /* tab block? */ 3244e98e3e1Schristos if (*file->pos == '\t') 3254e98e3e1Schristos { 3264e98e3e1Schristos char *chp = file->pos; 3274e98e3e1Schristos entry = new_table_entry (file, table_code_entry); 3284e98e3e1Schristos /* determine how many lines are involved - look for <nl> !<tab> */ 3294e98e3e1Schristos { 3304e98e3e1Schristos int nr_lines = 0; 3314e98e3e1Schristos int nr_blank_lines = 0; 3324e98e3e1Schristos while (1) 3334e98e3e1Schristos { 3344e98e3e1Schristos if (*file->pos == '\t') 3354e98e3e1Schristos { 3364e98e3e1Schristos nr_lines = nr_lines + nr_blank_lines + 1; 3374e98e3e1Schristos nr_blank_lines = 0; 3384e98e3e1Schristos next_line (file); 3394e98e3e1Schristos } 3404e98e3e1Schristos else 3414e98e3e1Schristos { 3424e98e3e1Schristos file->pos = skip_spaces (file->pos); 3434e98e3e1Schristos if (*file->pos != '\n') 3444e98e3e1Schristos break; 3454e98e3e1Schristos nr_blank_lines++; 3464e98e3e1Schristos next_line (file); 3474e98e3e1Schristos } 3484e98e3e1Schristos } 3494e98e3e1Schristos set_nr_table_entry_fields (entry, nr_lines); 3504e98e3e1Schristos } 3514e98e3e1Schristos /* now enter each line */ 3524e98e3e1Schristos { 3534e98e3e1Schristos int line_nr; 3544e98e3e1Schristos for (line_nr = 0; line_nr < entry->nr_fields; line_nr++) 3554e98e3e1Schristos { 3564e98e3e1Schristos if (*chp == '\t') 3574e98e3e1Schristos entry->field[line_nr] = chp + 1; 3584e98e3e1Schristos else 3594e98e3e1Schristos entry->field[line_nr] = ""; /* blank */ 3604e98e3e1Schristos chp = skip_to_null (chp) + 1; 3614e98e3e1Schristos } 3624e98e3e1Schristos } 3634e98e3e1Schristos break; 3644e98e3e1Schristos } 3654e98e3e1Schristos 3664e98e3e1Schristos /* cpp directive? */ 3674e98e3e1Schristos if (file->pos[0] == '#') 3684e98e3e1Schristos { 3694e98e3e1Schristos char *chp = skip_spaces (file->pos + 1); 3704e98e3e1Schristos 3714e98e3e1Schristos /* cpp line-nr directive - # <line-nr> "<file>" */ 3724e98e3e1Schristos if (isdigit (*chp) 3734e98e3e1Schristos && *skip_digits (chp) == ' ' 3744e98e3e1Schristos && *skip_spaces (skip_digits (chp)) == '"') 3754e98e3e1Schristos { 3764e98e3e1Schristos int line_nr; 3774e98e3e1Schristos char *file_name; 3784e98e3e1Schristos file->pos = chp; 3794e98e3e1Schristos /* parse the number */ 3804e98e3e1Schristos line_nr = atoi (file->pos) - 1; 3814e98e3e1Schristos /* skip to the file name */ 3824e98e3e1Schristos while (file->pos[0] != '0' 3834e98e3e1Schristos && file->pos[0] != '"' && file->pos[0] != '\0') 3844e98e3e1Schristos file->pos++; 3854e98e3e1Schristos if (file->pos[0] != '"') 3864e98e3e1Schristos error (&file->real_line, 3874e98e3e1Schristos "Missing opening quote in cpp directive\n"); 3884e98e3e1Schristos /* parse the file name */ 3894e98e3e1Schristos file->pos++; 3904e98e3e1Schristos file_name = file->pos; 3914e98e3e1Schristos while (file->pos[0] != '"' && file->pos[0] != '\0') 3924e98e3e1Schristos file->pos++; 3934e98e3e1Schristos if (file->pos[0] != '"') 3944e98e3e1Schristos error (&file->real_line, 3954e98e3e1Schristos "Missing closing quote in cpp directive\n"); 3964e98e3e1Schristos file->pos[0] = '\0'; 3974e98e3e1Schristos file->pos++; 3984e98e3e1Schristos file->pos = skip_to_nl (file->pos); 3994e98e3e1Schristos if (file->pos[0] != '\n') 4004e98e3e1Schristos error (&file->real_line, 4014e98e3e1Schristos "Missing newline in cpp directive\n"); 4024e98e3e1Schristos file->pseudo_line.file_name = file_name; 4034e98e3e1Schristos file->pseudo_line.line_nr = line_nr; 4044e98e3e1Schristos next_line (file); 4054e98e3e1Schristos continue; 4064e98e3e1Schristos } 4074e98e3e1Schristos 4084e98e3e1Schristos /* #define and #undef - not implemented yet */ 4094e98e3e1Schristos 4104e98e3e1Schristos /* Old style # comment */ 4114e98e3e1Schristos next_line (file); 4124e98e3e1Schristos continue; 4134e98e3e1Schristos } 4144e98e3e1Schristos 4154e98e3e1Schristos /* blank line or end-of-file? */ 4164e98e3e1Schristos file->pos = skip_spaces (file->pos); 4174e98e3e1Schristos if (*file->pos == '\0') 4184e98e3e1Schristos error (&file->pseudo_line, "Missing <nl> at end of file\n"); 4194e98e3e1Schristos if (*file->pos == '\n') 4204e98e3e1Schristos { 4214e98e3e1Schristos next_line (file); 4224e98e3e1Schristos continue; 4234e98e3e1Schristos } 4244e98e3e1Schristos 4254e98e3e1Schristos /* comment - leading // or # - skip */ 4264e98e3e1Schristos if ((file->pos[0] == '/' && file->pos[1] == '/') 4274e98e3e1Schristos || (file->pos[0] == '#')) 4284e98e3e1Schristos { 4294e98e3e1Schristos next_line (file); 4304e98e3e1Schristos continue; 4314e98e3e1Schristos } 4324e98e3e1Schristos 4334e98e3e1Schristos /* colon field */ 4344e98e3e1Schristos { 4354e98e3e1Schristos char *chp = file->pos; 4364e98e3e1Schristos entry = new_table_entry (file, table_colon_entry); 4374e98e3e1Schristos next_line (file); 4384e98e3e1Schristos /* figure out how many fields */ 4394e98e3e1Schristos { 4404e98e3e1Schristos int nr_fields = 1; 4414e98e3e1Schristos char *tmpch = chp; 4424e98e3e1Schristos while (1) 4434e98e3e1Schristos { 4444e98e3e1Schristos tmpch = skip_to_separator (tmpch, "\\:"); 4454e98e3e1Schristos if (*tmpch == '\\') 4464e98e3e1Schristos { 4474e98e3e1Schristos /* eat the escaped character */ 4484e98e3e1Schristos char *cp = tmpch; 4494e98e3e1Schristos while (cp[1] != '\0') 4504e98e3e1Schristos { 4514e98e3e1Schristos cp[0] = cp[1]; 4524e98e3e1Schristos cp++; 4534e98e3e1Schristos } 4544e98e3e1Schristos cp[0] = '\0'; 4554e98e3e1Schristos tmpch++; 4564e98e3e1Schristos } 4574e98e3e1Schristos else if (*tmpch != ':') 4584e98e3e1Schristos break; 4594e98e3e1Schristos else 4604e98e3e1Schristos { 4614e98e3e1Schristos *tmpch = '\0'; 4624e98e3e1Schristos tmpch++; 4634e98e3e1Schristos nr_fields++; 4644e98e3e1Schristos } 4654e98e3e1Schristos } 4664e98e3e1Schristos set_nr_table_entry_fields (entry, nr_fields); 4674e98e3e1Schristos } 4684e98e3e1Schristos /* now parse them */ 4694e98e3e1Schristos { 4704e98e3e1Schristos int field_nr; 4714e98e3e1Schristos for (field_nr = 0; field_nr < entry->nr_fields; field_nr++) 4724e98e3e1Schristos { 4734e98e3e1Schristos chp = skip_spaces (chp); 4744e98e3e1Schristos entry->field[field_nr] = chp; 4754e98e3e1Schristos chp = skip_to_null (chp); 4764e98e3e1Schristos *back_spaces (entry->field[field_nr], chp) = '\0'; 4774e98e3e1Schristos chp++; 4784e98e3e1Schristos } 4794e98e3e1Schristos } 4804e98e3e1Schristos break; 4814e98e3e1Schristos } 4824e98e3e1Schristos 4834e98e3e1Schristos } 4844e98e3e1Schristos 4854e98e3e1Schristos ASSERT (entry == NULL || entry->field[entry->nr_fields] == NULL); 4864e98e3e1Schristos return entry; 4874e98e3e1Schristos } 4884e98e3e1Schristos 4894e98e3e1Schristos extern void 4904b169a6bSchristos table_print_code (lf *file, const table_entry *entry) 4914e98e3e1Schristos { 4924e98e3e1Schristos int field_nr; 4934e98e3e1Schristos for (field_nr = 0; field_nr < entry->nr_fields; field_nr++) 4944e98e3e1Schristos { 4954e98e3e1Schristos char *chp = entry->field[field_nr]; 4964e98e3e1Schristos int in_bit_field = 0; 4974e98e3e1Schristos if (*chp == '#') 4984e98e3e1Schristos lf_indent_suppress (file); 4994e98e3e1Schristos while (*chp != '\0') 5004e98e3e1Schristos { 5014e98e3e1Schristos if (chp[0] == '{' && !isspace (chp[1]) && chp[1] != '\0') 5024e98e3e1Schristos { 5034e98e3e1Schristos in_bit_field = 1; 504*71f62182Schristos lf_putchr (file, '_'); 5054e98e3e1Schristos } 5064e98e3e1Schristos else if (in_bit_field && chp[0] == ':') 5074e98e3e1Schristos { 508*71f62182Schristos lf_putchr (file, '_'); 5094e98e3e1Schristos } 5104e98e3e1Schristos else if (in_bit_field && *chp == '}') 5114e98e3e1Schristos { 512*71f62182Schristos lf_putchr (file, '_'); 5134e98e3e1Schristos in_bit_field = 0; 5144e98e3e1Schristos } 5154e98e3e1Schristos else 5164e98e3e1Schristos { 517*71f62182Schristos lf_putchr (file, *chp); 5184e98e3e1Schristos } 5194e98e3e1Schristos chp++; 5204e98e3e1Schristos } 5214e98e3e1Schristos if (in_bit_field) 5224e98e3e1Schristos { 5234e98e3e1Schristos line_ref line = *entry->line; 5244e98e3e1Schristos line.line_nr += field_nr; 5254e98e3e1Schristos error (&line, "Bit field brace miss match\n"); 5264e98e3e1Schristos } 527*71f62182Schristos lf_putchr (file, '\n'); 5284e98e3e1Schristos } 5294e98e3e1Schristos } 5304e98e3e1Schristos 5314e98e3e1Schristos 5324e98e3e1Schristos void 5334b169a6bSchristos dump_line_ref (lf *file, 5344b169a6bSchristos const char *prefix, 5354b169a6bSchristos const line_ref *line, 5364b169a6bSchristos const char *suffix) 5374e98e3e1Schristos { 5384b169a6bSchristos lf_printf (file, "%s(line_ref*) %p", prefix, line); 5394e98e3e1Schristos if (line != NULL) 5404e98e3e1Schristos { 5414e98e3e1Schristos lf_indent (file, +1); 5424e98e3e1Schristos lf_printf (file, "\n(line_nr %d)", line->line_nr); 5434e98e3e1Schristos lf_printf (file, "\n(file_name %s)", line->file_name); 5444e98e3e1Schristos lf_indent (file, -1); 5454e98e3e1Schristos } 5464e98e3e1Schristos lf_printf (file, "%s", suffix); 5474e98e3e1Schristos } 5484e98e3e1Schristos 5494e98e3e1Schristos 5504e98e3e1Schristos static const char * 5514e98e3e1Schristos table_entry_type_to_str (table_entry_type type) 5524e98e3e1Schristos { 5534e98e3e1Schristos switch (type) 5544e98e3e1Schristos { 5554e98e3e1Schristos case table_code_entry: 5564e98e3e1Schristos return "code-entry"; 5574e98e3e1Schristos case table_colon_entry: 5584e98e3e1Schristos return "colon-entry"; 5594e98e3e1Schristos } 5604e98e3e1Schristos return "*invalid*"; 5614e98e3e1Schristos } 5624e98e3e1Schristos 5634e98e3e1Schristos void 5644e98e3e1Schristos dump_table_entry (lf *file, 5654b169a6bSchristos const char *prefix, 5664b169a6bSchristos const table_entry *entry, 5674b169a6bSchristos const char *suffix) 5684e98e3e1Schristos { 5694b169a6bSchristos lf_printf (file, "%s(table_entry*) %p", prefix, entry); 5704e98e3e1Schristos if (entry != NULL) 5714e98e3e1Schristos { 5724e98e3e1Schristos int field; 5734e98e3e1Schristos lf_indent (file, +1); 5744e98e3e1Schristos dump_line_ref (file, "\n(line ", entry->line, ")"); 5754e98e3e1Schristos lf_printf (file, "\n(type %s)", table_entry_type_to_str (entry->type)); 5764e98e3e1Schristos lf_printf (file, "\n(nr_fields %d)", entry->nr_fields); 5774e98e3e1Schristos lf_printf (file, "\n(fields"); 5784e98e3e1Schristos lf_indent (file, +1); 5794e98e3e1Schristos for (field = 0; field < entry->nr_fields; field++) 5804e98e3e1Schristos lf_printf (file, "\n\"%s\"", entry->field[field]); 5814e98e3e1Schristos lf_indent (file, -1); 5824e98e3e1Schristos lf_printf (file, ")"); 5834e98e3e1Schristos lf_indent (file, -1); 5844e98e3e1Schristos } 5854e98e3e1Schristos lf_printf (file, "%s", suffix); 5864e98e3e1Schristos } 5874e98e3e1Schristos 5884e98e3e1Schristos 5894e98e3e1Schristos #ifdef MAIN 5904e98e3e1Schristos int 5914e98e3e1Schristos main (int argc, char **argv) 5924e98e3e1Schristos { 5934e98e3e1Schristos table *t; 5944e98e3e1Schristos table_entry *entry; 5954e98e3e1Schristos lf *l; 5964e98e3e1Schristos int line_nr; 5974e98e3e1Schristos 5984e98e3e1Schristos if (argc != 2) 5994e98e3e1Schristos { 6004e98e3e1Schristos printf ("Usage: table <file>\n"); 6014e98e3e1Schristos exit (1); 6024e98e3e1Schristos } 6034e98e3e1Schristos 6044e98e3e1Schristos t = table_open (argv[1]); 6054e98e3e1Schristos l = lf_open ("-", "stdout", lf_omit_references, lf_is_text, "tmp-table"); 6064e98e3e1Schristos 6074e98e3e1Schristos line_nr = 0; 6084e98e3e1Schristos do 6094e98e3e1Schristos { 6104e98e3e1Schristos char line[10]; 6114e98e3e1Schristos entry = table_read (t); 6124e98e3e1Schristos line_nr++; 6134e98e3e1Schristos sprintf (line, "(%d ", line_nr); 6144e98e3e1Schristos dump_table_entry (l, line, entry, ")\n"); 6154e98e3e1Schristos } 6164e98e3e1Schristos while (entry != NULL); 6174e98e3e1Schristos 6184e98e3e1Schristos return 0; 6194e98e3e1Schristos } 6204e98e3e1Schristos #endif 621