xref: /netbsd-src/external/gpl3/gdb.old/dist/sim/ppc/table.c (revision 8b657b0747480f8989760d71343d6dd33f8d4cf9)
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' && *file->pos != '\r')
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' && *file->pos != '\r') {
223     file->pos++;
224   }
225   if (*file->pos == '\r') {
226     *file->pos = '\0';
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' && *file->pos != '\r')
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' && *file->pos != '\r') {
262       file->pos++;
263     }
264     if (*file->pos == '\r') {
265       *file->pos = '\0';
266       file->pos++;
267     }
268     if (*file->pos == '\n') {
269       *file->pos = '\0';
270       file->pos++;
271     }
272 
273     file->line_nr++;
274     model->line_nr = file->line_nr;
275   }
276 
277   entry->line_nr = file->line_nr;
278 
279   /* if following lines are tab indented, put in the annex */
280   if (*file->pos == '\t') {
281     entry->annex = file->pos;
282     do {
283       do {
284 	file->pos++;
285       } while (*file->pos != '\0' && *file->pos != '\n' && *file->pos != '\r');
286       if (*file->pos == '\n' || *file->pos == '\r') {
287 	char *save_pos = ++file->pos;
288 	int extra_lines = 0;
289 	file->line_nr++;
290 	/* Allow tab indented to have blank lines */
291 	while (*save_pos == '\n' || *save_pos == '\r') {
292 	  save_pos++;
293 	  extra_lines++;
294 	}
295 	if (*save_pos == '\t') {
296 	  file->pos = save_pos;
297 	  file->line_nr += extra_lines;
298 	}
299       }
300     } while (*file->pos != '\0' && *file->pos == '\t');
301     if (file->pos[-1] == '\n' || file->pos[-1] == '\r')
302       file->pos[-1] = '\0';
303   }
304   else
305     entry->annex = NULL;
306 
307   /* return it */
308   return entry;
309 
310 }
311 
312 
313 extern void
314 dump_table_entry(table_entry *entry,
315 		 int indent)
316 {
317   printf("(table_entry*)%p\n", entry);
318 
319   if (entry != NULL) {
320     int field;
321     char sep;
322 
323     sep = ' ';
324     dumpf(indent, "(fields");
325     for (field = 0; field < entry->nr_fields; field++) {
326       printf("%c%s", sep, entry->fields[field]);
327       sep = ':';
328     }
329     printf(")\n");
330 
331     dumpf(indent, "(line_nr %d)\n", entry->line_nr);
332 
333     dumpf(indent, "(file_name %s)\n", entry->file_name);
334 
335     dumpf(indent, "(annex\n%s\n", entry->annex);
336     dumpf(indent, " )\n");
337 
338   }
339 }
340 
341 
342 extern void
343 table_entry_print_cpp_line_nr(lf *file,
344 			      table_entry *entry)
345 {
346   lf_print__external_reference(file, entry->line_nr, entry->file_name);
347 }
348 
349 
350