[gdbsupport] Add gdb::array_view::{iterator,const_iterator}
[binutils-gdb.git] / sim / ppc / table.c
blob94f04921deb7b3b1ae414256fef9027ff7c23ec6
1 /* This file is part of the program psim.
3 Copyright (C) 1994-1995, 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 3 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, see <http://www.gnu.org/licenses/>.
21 #include <sys/types.h>
22 #include <sys/stat.h>
23 #include <stdio.h>
24 #include <fcntl.h>
25 #include <ctype.h>
27 #include "misc.h"
28 #include "lf.h"
29 #include "table.h"
30 #include "dumpf.h"
32 #include <unistd.h>
33 #include <stdlib.h>
35 typedef struct _open_table open_table;
36 struct _open_table {
37 size_t size;
38 char *buffer;
39 char *pos;
40 int line_nr;
41 int nr_fields;
42 int nr_model_fields;
43 char *file_name;
44 open_table *parent;
45 table *root;
47 struct _table {
48 open_table *current;
51 void
52 table_push (table *root,
53 table_include *includes,
54 const char *file_name,
55 int nr_fields,
56 int nr_model_fields)
59 int fd;
60 struct stat stat_buf;
61 open_table *file;
62 table_include dummy;
63 table_include *include = &dummy;
64 int nr;
66 /* dummy up a search of this directory */
67 dummy.next = includes;
68 dummy.dir = "";
70 /* create a file descriptor */
71 file = ZALLOC (open_table);
72 ASSERT(file != NULL);
73 file->nr_fields = nr_fields;
74 file->nr_model_fields = nr_model_fields;
75 file->root = root;
76 file->parent = root->current;
77 root->current = file;
79 while (1)
81 /* save the file name */
82 char *dup_name = NZALLOC (char, strlen (include->dir) + strlen (file_name) + 2);
83 if (dup_name == NULL)
85 perror (file_name);
86 exit (1);
88 if (include->dir[0] != '\0')
90 strcat (dup_name, include->dir);
91 strcat (dup_name, "/");
93 strcat (dup_name, file_name);
94 file->file_name = dup_name;
95 /* open the file */
96 fd = open (dup_name, O_RDONLY, 0);
97 if (fd >= 0)
98 break;
99 /* free (dup_name); */
100 if (include->next == NULL)
102 ERROR ("Problem opening file `%s'\n", file_name);
103 perror (file_name);
104 exit (1);
106 include = include->next;
109 /* determine the size */
110 if (fstat(fd, &stat_buf) < 0) {
111 perror("table_open.fstat");
112 exit(1);
114 file->size = stat_buf.st_size;
116 /* allocate this much memory */
117 file->buffer = (char*)zalloc(file->size+1);
118 if(file->buffer == NULL) {
119 perror("table_open.calloc.file->size+1");
120 exit(1);
122 file->pos = file->buffer;
124 /* read it in */
125 #ifdef __CYGWIN32__
126 if ((file->size) && ((nr = read(fd, file->buffer, file->size)) <= 0)) {
127 #else
128 if ((nr = read(fd, file->buffer, file->size)) < file->size) {
129 #endif
130 perror("table_open.read");
131 exit(1);
133 file->size = nr;
134 file->buffer[file->size] = '\0';
136 /* done */
137 close(fd);
140 extern table *
141 table_open(const char *file_name,
142 int nr_fields,
143 int nr_model_fields)
145 table *root;
147 /* create a file descriptor */
148 root = ZALLOC (table);
149 if (root == NULL)
151 perror (file_name);
152 exit (1);
155 table_push (root, NULL, file_name, nr_fields, nr_model_fields);
156 return root;
159 extern table_entry *
160 table_entry_read(table *root)
162 open_table *file = root->current;
163 int field;
164 table_entry *entry;
166 /* skip comments/blanks */
167 while(1) {
168 /* end-of-file? */
169 while (*file->pos == '\0')
171 if (file->parent != NULL)
173 file = file->parent;
174 root->current = file;
176 else
177 return NULL;
179 /* leading white space */
180 while (*file->pos != '\0'
181 && *file->pos != '\n'
182 && isspace(*file->pos))
183 file->pos++;
184 /* comment */
185 if (*file->pos == '#') {
186 do {
187 file->pos++;
188 } while (*file->pos != '\0' && *file->pos != '\n');
190 /* end of line? */
191 if (*file->pos == '\n') {
192 file->pos++;
193 file->line_nr++;
195 else
196 break;
199 /* create this new entry */
200 entry = (table_entry*)zalloc(sizeof(table_entry)
201 + (file->nr_fields + 1) * sizeof(char*));
202 ASSERT(entry != NULL);
203 entry->file_name = file->file_name;
204 entry->nr_fields = file->nr_fields;
206 /* break the line into its colon delimitered fields */
207 for (field = 0; field < file->nr_fields-1; field++) {
208 entry->fields[field] = file->pos;
209 while(*file->pos && *file->pos != ':' && *file->pos != '\n' && *file->pos != '\r')
210 file->pos++;
211 if (*file->pos == ':') {
212 *file->pos = '\0';
213 file->pos++;
217 /* any trailing stuff not the last field */
218 ASSERT(field == file->nr_fields-1);
219 entry->fields[field] = file->pos;
220 while (*file->pos && *file->pos != '\n' && *file->pos != '\r') {
221 file->pos++;
223 if (*file->pos == '\r') {
224 *file->pos = '\0';
225 file->pos++;
227 if (*file->pos == '\n') {
228 *file->pos = '\0';
229 file->pos++;
231 file->line_nr++;
233 /* if following lines begin with a star, add them to the model
234 section. */
235 while ((file->nr_model_fields > 0) && (*file->pos == '*')) {
236 table_model_entry *model = (table_model_entry*)zalloc(sizeof(table_model_entry)
237 + (file->nr_model_fields + 1) * sizeof(char*));
238 if (entry->model_last)
239 entry->model_last->next = model;
240 else
241 entry->model_first = model;
242 entry->model_last = model;
244 /* break the line into its colon delimitered fields */
245 file->pos++;
246 for (field = 0; field < file->nr_model_fields-1; field++) {
247 model->fields[field] = file->pos;
248 while(*file->pos && *file->pos != ':' && *file->pos != '\n' && *file->pos != '\r')
249 file->pos++;
250 if (*file->pos == ':') {
251 *file->pos = '\0';
252 file->pos++;
256 /* any trailing stuff not the last field */
257 ASSERT(field == file->nr_model_fields-1);
258 model->fields[field] = file->pos;
259 while (*file->pos && *file->pos != '\n' && *file->pos != '\r') {
260 file->pos++;
262 if (*file->pos == '\r') {
263 *file->pos = '\0';
264 file->pos++;
266 if (*file->pos == '\n') {
267 *file->pos = '\0';
268 file->pos++;
271 file->line_nr++;
272 model->line_nr = file->line_nr;
275 entry->line_nr = file->line_nr;
277 /* if following lines are tab indented, put in the annex */
278 if (*file->pos == '\t') {
279 entry->annex = file->pos;
280 do {
281 do {
282 file->pos++;
283 } while (*file->pos != '\0' && *file->pos != '\n' && *file->pos != '\r');
284 if (*file->pos == '\n' || *file->pos == '\r') {
285 char *save_pos = ++file->pos;
286 int extra_lines = 0;
287 file->line_nr++;
288 /* Allow tab indented to have blank lines */
289 while (*save_pos == '\n' || *save_pos == '\r') {
290 save_pos++;
291 extra_lines++;
293 if (*save_pos == '\t') {
294 file->pos = save_pos;
295 file->line_nr += extra_lines;
298 } while (*file->pos != '\0' && *file->pos == '\t');
299 if (file->pos[-1] == '\n' || file->pos[-1] == '\r')
300 file->pos[-1] = '\0';
302 else
303 entry->annex = NULL;
305 /* return it */
306 return entry;
311 extern void
312 dump_table_entry(table_entry *entry,
313 int indent)
315 printf("(table_entry*)%p\n", entry);
317 if (entry != NULL) {
318 int field;
319 char sep;
321 sep = ' ';
322 dumpf(indent, "(fields");
323 for (field = 0; field < entry->nr_fields; field++) {
324 printf("%c%s", sep, entry->fields[field]);
325 sep = ':';
327 printf(")\n");
329 dumpf(indent, "(line_nr %d)\n", entry->line_nr);
331 dumpf(indent, "(file_name %s)\n", entry->file_name);
333 dumpf(indent, "(annex\n%s\n", entry->annex);
334 dumpf(indent, " )\n");
340 extern void
341 table_entry_print_cpp_line_nr(lf *file,
342 table_entry *entry)
344 lf_print__external_ref(file, entry->line_nr, entry->file_name);