]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - sim/ppc/table.c
sim: create a makefile fragment to pass common settings down
[thirdparty/binutils-gdb.git] / sim / ppc / table.c
1 /* This file is part of the program psim.
2
3 Copyright (C) 1994-1995, Andrew Cagney <cagney@highland.com.au>
4
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.
9
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.
14
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/>.
17
18 */
19
20
21 #include <sys/types.h>
22 #include <sys/stat.h>
23 #include <stdio.h>
24 #include <fcntl.h>
25 #include <ctype.h>
26
27 #include "build-config.h"
28 #include "misc.h"
29 #include "lf.h"
30 #include "table.h"
31
32 #ifdef HAVE_UNISTD_H
33 #include <unistd.h>
34 #endif
35 #include <stdlib.h>
36
37 typedef struct _open_table open_table;
38 struct _open_table {
39 size_t size;
40 char *buffer;
41 char *pos;
42 int line_nr;
43 int nr_fields;
44 int nr_model_fields;
45 char *file_name;
46 open_table *parent;
47 table *root;
48 };
49 struct _table {
50 open_table *current;
51 };
52
53 void
54 table_push (table *root,
55 table_include *includes,
56 const char *file_name,
57 int nr_fields,
58 int nr_model_fields)
59
60 {
61 int fd;
62 struct stat stat_buf;
63 open_table *file;
64 table_include dummy;
65 table_include *include = &dummy;
66 int nr;
67
68 /* dummy up a search of this directory */
69 dummy.next = includes;
70 dummy.dir = "";
71
72 /* create a file descriptor */
73 file = ZALLOC (open_table);
74 ASSERT(file != NULL);
75 file->nr_fields = nr_fields;
76 file->nr_model_fields = nr_model_fields;
77 file->root = root;
78 file->parent = root->current;
79 root->current = file;
80
81 while (1)
82 {
83 /* save the file name */
84 char *dup_name = NZALLOC (char, strlen (include->dir) + strlen (file_name) + 2);
85 if (dup_name == NULL)
86 {
87 perror (file_name);
88 exit (1);
89 }
90 if (include->dir[0] != '\0')
91 {
92 strcat (dup_name, include->dir);
93 strcat (dup_name, "/");
94 }
95 strcat (dup_name, file_name);
96 file->file_name = dup_name;
97 /* open the file */
98 fd = open (dup_name, O_RDONLY, 0);
99 if (fd >= 0)
100 break;
101 /* free (dup_name); */
102 if (include->next == NULL)
103 {
104 error ("Problem opening file `%s'\n", file_name);
105 perror (file_name);
106 exit (1);
107 }
108 include = include->next;
109 }
110
111 /* determine the size */
112 if (fstat(fd, &stat_buf) < 0) {
113 perror("table_open.fstat");
114 exit(1);
115 }
116 file->size = stat_buf.st_size;
117
118 /* allocate this much memory */
119 file->buffer = (char*)zalloc(file->size+1);
120 if(file->buffer == NULL) {
121 perror("table_open.calloc.file->size+1");
122 exit(1);
123 }
124 file->pos = file->buffer;
125
126 /* read it in */
127 #ifdef __CYGWIN32__
128 if ((file->size) && ((nr = read(fd, file->buffer, file->size)) <= 0)) {
129 #else
130 if ((nr = read(fd, file->buffer, file->size)) < file->size) {
131 #endif
132 perror("table_open.read");
133 exit(1);
134 }
135 file->size = nr;
136 file->buffer[file->size] = '\0';
137
138 /* done */
139 close(fd);
140 }
141
142 extern table *
143 table_open(const char *file_name,
144 int nr_fields,
145 int nr_model_fields)
146 {
147 table *root;
148
149 /* create a file descriptor */
150 root = ZALLOC (table);
151 if (root == NULL)
152 {
153 perror (file_name);
154 exit (1);
155 }
156
157 table_push (root, NULL, file_name, nr_fields, nr_model_fields);
158 return root;
159 }
160
161 extern table_entry *
162 table_entry_read(table *root)
163 {
164 open_table *file = root->current;
165 int field;
166 table_entry *entry;
167
168 /* skip comments/blanks */
169 while(1) {
170 /* end-of-file? */
171 while (*file->pos == '\0')
172 {
173 if (file->parent != NULL)
174 {
175 file = file->parent;
176 root->current = file;
177 }
178 else
179 return NULL;
180 }
181 /* leading white space */
182 while (*file->pos != '\0'
183 && *file->pos != '\n'
184 && isspace(*file->pos))
185 file->pos++;
186 /* comment */
187 if (*file->pos == '#') {
188 do {
189 file->pos++;
190 } while (*file->pos != '\0' && *file->pos != '\n');
191 }
192 /* end of line? */
193 if (*file->pos == '\n') {
194 file->pos++;
195 file->line_nr++;
196 }
197 else
198 break;
199 }
200
201 /* create this new entry */
202 entry = (table_entry*)zalloc(sizeof(table_entry)
203 + (file->nr_fields + 1) * sizeof(char*));
204 ASSERT(entry != NULL);
205 entry->file_name = file->file_name;
206 entry->nr_fields = file->nr_fields;
207
208 /* break the line into its colon delimitered fields */
209 for (field = 0; field < file->nr_fields-1; field++) {
210 entry->fields[field] = file->pos;
211 while(*file->pos && *file->pos != ':' && *file->pos != '\n')
212 file->pos++;
213 if (*file->pos == ':') {
214 *file->pos = '\0';
215 file->pos++;
216 }
217 }
218
219 /* any trailing stuff not the last field */
220 ASSERT(field == file->nr_fields-1);
221 entry->fields[field] = file->pos;
222 while (*file->pos && *file->pos != '\n') {
223 file->pos++;
224 }
225 if (*file->pos == '\n') {
226 *file->pos = '\0';
227 file->pos++;
228 }
229 file->line_nr++;
230
231 /* if following lines begin with a star, add them to the model
232 section. */
233 while ((file->nr_model_fields > 0) && (*file->pos == '*')) {
234 table_model_entry *model = (table_model_entry*)zalloc(sizeof(table_model_entry)
235 + (file->nr_model_fields + 1) * sizeof(char*));
236 if (entry->model_last)
237 entry->model_last->next = model;
238 else
239 entry->model_first = model;
240 entry->model_last = model;
241
242 /* break the line into its colon delimitered fields */
243 file->pos++;
244 for (field = 0; field < file->nr_model_fields-1; field++) {
245 model->fields[field] = file->pos;
246 while(*file->pos && *file->pos != ':' && *file->pos != '\n')
247 file->pos++;
248 if (*file->pos == ':') {
249 *file->pos = '\0';
250 file->pos++;
251 }
252 }
253
254 /* any trailing stuff not the last field */
255 ASSERT(field == file->nr_model_fields-1);
256 model->fields[field] = file->pos;
257 while (*file->pos && *file->pos != '\n') {
258 file->pos++;
259 }
260 if (*file->pos == '\n') {
261 *file->pos = '\0';
262 file->pos++;
263 }
264
265 file->line_nr++;
266 model->line_nr = file->line_nr;
267 }
268
269 entry->line_nr = file->line_nr;
270
271 /* if following lines are tab indented, put in the annex */
272 if (*file->pos == '\t') {
273 entry->annex = file->pos;
274 do {
275 do {
276 file->pos++;
277 } while (*file->pos != '\0' && *file->pos != '\n');
278 if (*file->pos == '\n') {
279 char *save_pos = ++file->pos;
280 int extra_lines = 0;
281 file->line_nr++;
282 /* Allow tab indented to have blank lines */
283 while (*save_pos == '\n') {
284 save_pos++;
285 extra_lines++;
286 }
287 if (*save_pos == '\t') {
288 file->pos = save_pos;
289 file->line_nr += extra_lines;
290 }
291 }
292 } while (*file->pos != '\0' && *file->pos == '\t');
293 if (file->pos[-1] == '\n')
294 file->pos[-1] = '\0';
295 }
296 else
297 entry->annex = NULL;
298
299 /* return it */
300 return entry;
301
302 }
303
304
305 extern void
306 dump_table_entry(table_entry *entry,
307 int indent)
308 {
309 printf("(table_entry*)%p\n", entry);
310
311 if (entry != NULL) {
312 int field;
313 char sep;
314
315 sep = ' ';
316 dumpf(indent, "(fields");
317 for (field = 0; field < entry->nr_fields; field++) {
318 printf("%c%s", sep, entry->fields[field]);
319 sep = ':';
320 }
321 printf(")\n");
322
323 dumpf(indent, "(line_nr %d)\n", entry->line_nr);
324
325 dumpf(indent, "(file_name %s)\n", entry->file_name);
326
327 dumpf(indent, "(annex\n%s\n", entry->annex);
328 dumpf(indent, " )\n");
329
330 }
331 }
332
333
334 extern void
335 table_entry_print_cpp_line_nr(lf *file,
336 table_entry *entry)
337 {
338 lf_print__external_reference(file, entry->line_nr, entry->file_name);
339 }
340
341