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