1 /* This file is part of the program psim.
3 Copyright (C) 1994-1995,1997 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 2 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, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 #include <sys/types.h>
49 int current_file_line_offset
;
50 char *current_file_name
;
54 table_open(const char *file_name
,
62 /* create a file descriptor */
65 file
->nr_fields
= nr_fields
;
66 file
->nr_model_fields
= nr_model_fields
;
68 /* save the file name */
69 file
->file_name
= (char*)zalloc(strlen(file_name
) + 1);
70 ASSERT(file
->file_name
!= NULL
);
71 strcpy(file
->file_name
, file_name
);
72 file
->current_file_name
= file
->file_name
;
75 fd
= open(file
->file_name
, O_RDONLY
, 0);
77 perror(file
->file_name
);
81 /* determine the size */
82 if (fstat(fd
, &stat_buf
) < 0) {
83 perror("table_open.fstat");
86 file
->size
= stat_buf
.st_size
;
88 /* allocate this much memory */
89 file
->buffer
= (char*)zalloc(file
->size
+1);
90 ASSERT(file
->buffer
!= NULL
);
91 file
->pos
= file
->buffer
;
94 if (read(fd
, file
->buffer
, file
->size
) < file
->size
) {
95 perror(file
->file_name
);
98 file
->buffer
[file
->size
] = '\0';
100 /* set the initial line numbering */
102 file
->current_file_line_offset
= 0;
111 table_entry_read(table
*file
)
116 /* skip comments/blanks */
118 /* leading white space */
119 while (*file
->pos
!= '\0'
120 && *file
->pos
!= '\n'
121 && isspace(*file
->pos
))
123 /* cpp line nr directive - # <line-nr> "<file>" */
124 if (file
->pos
[0] == '#'
125 && file
->pos
[1] == ' '
126 && isdigit(file
->pos
[2])) {
127 file
->pos
+= strlen("# ");
128 /* parse the number */
129 file
->current_file_line_offset
= atoi(file
->pos
) - file
->line_nr
- 2;
130 /* skip to the file name */
131 while (file
->pos
[0] != '0'
132 && file
->pos
[0] != '"'
133 && file
->pos
[0] != '\0')
135 if (file
->pos
[0] != '"') {
136 error("%s:%d: Missing opening quote",
140 /* parse the file name */
142 file
->current_file_name
= file
->pos
;
143 while (file
->pos
[0] != '"'
144 && file
->pos
[0] != '\0')
146 if (file
->pos
[0] != '"') {
147 error("%s:%d: Missing closing quote",
153 while (file
->pos
[0] != '\0'
154 && file
->pos
[0] != '\n')
156 if (file
->pos
[0] != '\n')
157 error("%s:%d: Missing newline",
161 /* comment - leading // or # - skip */
162 else if ((file
->pos
[0] == '/' && file
->pos
[1] == '/')
163 || (file
->pos
[0] == '#')) {
166 } while (*file
->pos
!= '\0' && *file
->pos
!= '\n');
169 if (*file
->pos
== '\n') {
176 if (*file
->pos
== '\0')
179 /* create this new entry */
180 entry
= (table_entry
*)zalloc(sizeof(table_entry
)
181 + (file
->nr_fields
+ 1) * sizeof(char*));
182 ASSERT(entry
!= NULL
);
183 entry
->file_name
= file
->current_file_name
;
184 entry
->nr_fields
= file
->nr_fields
;
186 /* break the line into its colon delimitered fields */
187 for (field
= 0; field
< file
->nr_fields
-1; field
++) {
188 entry
->fields
[field
] = file
->pos
;
189 while(*file
->pos
&& *file
->pos
!= ':' && *file
->pos
!= '\n')
191 if (*file
->pos
== ':') {
197 /* any trailing stuff not the last field */
198 ASSERT(field
== file
->nr_fields
-1);
199 entry
->fields
[field
] = file
->pos
;
200 while (*file
->pos
&& *file
->pos
!= '\n') {
203 if (*file
->pos
== '\n') {
209 /* If following lines being with a double quote ("), add them to the
210 list of assembler lines */
212 table_assembler_entry
**current
= &entry
->assembler
;
213 while (*file
->pos
== '"') {
217 const char *condition
;
218 int strlen_condition
;
220 /* skip over the format string */
224 if (file
->pos
[0] == '\\' && file
->pos
[1] == '"')
228 } while (*file
->pos
!= '\0' && *file
->pos
!= '\n' && *file
->pos
!= '"');
229 if (*file
->pos
!= '"')
230 error ("%s:%d: Missing closing quote in assembler line",
234 strlen_format
= file
->pos
- format
;
236 /* skip over the boolean condition */
238 strlen_condition
= 0;
239 if (*file
->pos
== ':')
242 while (isspace(*file
->pos
) && *file
->pos
!= '\0' && *file
->pos
!= '\n')
244 condition
= file
->pos
;
245 while (*file
->pos
!= '\0' && *file
->pos
!= '\n')
247 strlen_condition
= file
->pos
- condition
;
250 /* create the new assembler entry */
251 *current
= ZALLOC (table_assembler_entry
);
252 tmpchp
= zalloc (strlen_format
+ 1);
253 strncpy (tmpchp
, format
, strlen_format
);
254 (*current
)->format
= tmpchp
;
255 (*current
)->file_name
= file
->file_name
;
256 (*current
)->line_nr
= file
->line_nr
;
257 if (condition
!= NULL
&& strlen_condition
> 0)
259 tmpchp
= zalloc (strlen_condition
+ 1);
260 strncpy (tmpchp
, condition
, strlen_condition
);
261 (*current
)->condition
= tmpchp
;
263 current
= &(*current
)->next
;
266 if (*file
->pos
!= '\n')
267 error ("%s:%d: Missing eoln in assembler line",
275 /* if following lines begin with a star, add them to the model
277 while ((file
->nr_model_fields
> 0) && (*file
->pos
== '*')) {
278 table_model_entry
*model
= (table_model_entry
*)zalloc(sizeof(table_model_entry
)
279 + (file
->nr_model_fields
+ 1) * sizeof(char*));
280 if (entry
->model_last
)
281 entry
->model_last
->next
= model
;
283 entry
->model_first
= model
;
284 entry
->model_last
= model
;
286 /* break the line into its colon delimitered fields */
288 for (field
= 0; field
< file
->nr_model_fields
-1; field
++) {
289 model
->fields
[field
] = file
->pos
;
290 while(*file
->pos
&& *file
->pos
!= ':' && *file
->pos
!= '\n')
292 if (*file
->pos
== ':') {
298 /* any trailing stuff not the last field */
299 ASSERT(field
== file
->nr_model_fields
-1);
300 model
->fields
[field
] = file
->pos
;
301 while (*file
->pos
&& *file
->pos
!= '\n') {
304 if (*file
->pos
== '\n') {
310 model
->line_nr
= file
->current_file_line_offset
+ file
->line_nr
;
313 entry
->line_nr
= file
->current_file_line_offset
+ file
->line_nr
;
315 /* if following lines are tab indented, put in the annex */
316 if (*file
->pos
== '\t') {
317 entry
->annex
= file
->pos
;
321 } while (*file
->pos
!= '\0' && *file
->pos
!= '\n');
322 if (*file
->pos
== '\n') {
323 char *save_pos
= ++file
->pos
;
326 /* Allow tab indented to have blank lines */
327 while (*save_pos
== '\n') {
331 if (*save_pos
== '\t') {
332 file
->pos
= save_pos
;
333 file
->line_nr
+= extra_lines
;
336 } while (*file
->pos
!= '\0' && *file
->pos
== '\t');
337 if (file
->pos
[-1] == '\n')
338 file
->pos
[-1] = '\0';
350 dump_table_entry(table_entry
*entry
,
353 printf("(table_entry*)%p\n", entry
);
360 dumpf(indent
, "(fields");
361 for (field
= 0; field
< entry
->nr_fields
; field
++) {
362 printf("%c%s", sep
, entry
->fields
[field
]);
367 dumpf(indent
, "(line_nr %d)\n", entry
->line_nr
);
369 dumpf(indent
, "(file_name %s)\n", entry
->file_name
);
371 dumpf(indent
, "(annex\n%s\n", entry
->annex
);
372 dumpf(indent
, " )\n");
379 table_entry_print_cpp_line_nr(lf
*file
,
382 lf_print__external_reference(file
, entry
->line_nr
, entry
->file_name
);
This page took 0.055037 seconds and 5 git commands to generate.