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>
27 #include "build-config.h"
35 typedef struct _open_table open_table
;
52 table_push (table
*root
,
53 table_include
*includes
,
54 const char *file_name
,
63 table_include
*include
= &dummy
;
66 /* dummy up a search of this directory */
67 dummy
.next
= includes
;
70 /* create a file descriptor */
71 file
= ZALLOC (open_table
);
73 file
->nr_fields
= nr_fields
;
74 file
->nr_model_fields
= nr_model_fields
;
76 file
->parent
= root
->current
;
81 /* save the file name */
82 char *dup_name
= NZALLOC (char, strlen (include
->dir
) + strlen (file_name
) + 2);
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
;
96 fd
= open (dup_name
, O_RDONLY
, 0);
99 /* free (dup_name); */
100 if (include
->next
== NULL
)
102 error ("Problem opening file `%s'\n", file_name
);
106 include
= include
->next
;
109 /* determine the size */
110 if (fstat(fd
, &stat_buf
) < 0) {
111 perror("table_open.fstat");
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");
122 file
->pos
= file
->buffer
;
126 if ((file
->size
) && ((nr
= read(fd
, file
->buffer
, file
->size
)) <= 0)) {
128 if ((nr
= read(fd
, file
->buffer
, file
->size
)) < file
->size
) {
130 perror("table_open.read");
134 file
->buffer
[file
->size
] = '\0';
141 table_open(const char *file_name
,
147 /* create a file descriptor */
148 root
= ZALLOC (table
);
155 table_push (root
, NULL
, file_name
, nr_fields
, nr_model_fields
);
160 table_entry_read(table
*root
)
162 open_table
*file
= root
->current
;
166 /* skip comments/blanks */
169 while (*file
->pos
== '\0')
171 if (file
->parent
!= NULL
)
174 root
->current
= file
;
179 /* leading white space */
180 while (*file
->pos
!= '\0'
181 && *file
->pos
!= '\n'
182 && isspace(*file
->pos
))
185 if (*file
->pos
== '#') {
188 } while (*file
->pos
!= '\0' && *file
->pos
!= '\n');
191 if (*file
->pos
== '\n') {
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')
211 if (*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') {
223 if (*file
->pos
== '\r') {
227 if (*file
->pos
== '\n') {
233 /* if following lines begin with a star, add them to the model
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
;
241 entry
->model_first
= model
;
242 entry
->model_last
= model
;
244 /* break the line into its colon delimitered fields */
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')
250 if (*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') {
262 if (*file
->pos
== '\r') {
266 if (*file
->pos
== '\n') {
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
;
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
;
288 /* Allow tab indented to have blank lines */
289 while (*save_pos
== '\n' || *save_pos
== '\r') {
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';
312 dump_table_entry(table_entry
*entry
,
315 printf("(table_entry*)%p\n", entry
);
322 dumpf(indent
, "(fields");
323 for (field
= 0; field
< entry
->nr_fields
; field
++) {
324 printf("%c%s", sep
, entry
->fields
[field
]);
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");
341 table_entry_print_cpp_line_nr(lf
*file
,
344 lf_print__external_reference(file
, entry
->line_nr
, entry
->file_name
);