]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - sim/ppc/lf.c
This commit was generated by cvs2svn to track changes on a CVS vendor
[thirdparty/binutils-gdb.git] / sim / ppc / lf.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 <stdio.h>
23 #include <stdarg.h>
24 #include <ctype.h>
25
26 #include "config.h"
27 #include "misc.h"
28 #include "lf.h"
29
30 #ifdef HAVE_STDLIB_H
31 #include <stdlib.h>
32 #endif
33
34 #ifdef HAVE_STRING_H
35 #include <string.h>
36 #else
37 #ifdef HAVE_STRINGS_H
38 #include <strings.h>
39 #endif
40 #endif
41
42 struct _lf {
43 FILE *stream;
44 int line_nr; /* nr complete lines written, curr line is line_nr+1 */
45 int indent;
46 int line_blank;
47 const char *name;
48 const char *program;
49 lf_file_references references;
50 lf_file_type type;
51 };
52
53
54 lf *
55 lf_open(char *name,
56 char *real_name,
57 lf_file_references references,
58 lf_file_type type,
59 const char *program)
60 {
61 /* create a file object */
62 lf *new_lf = ZALLOC(lf);
63 ASSERT(new_lf != NULL);
64 new_lf->references = references;
65 new_lf->type = type;
66 new_lf->name = (real_name == NULL ? name : real_name);
67 new_lf->program = program;
68 /* attach to stdout if pipe */
69 if (!strcmp(name, "-")) {
70 new_lf->stream = stdout;
71 }
72 else {
73 /* create a new file */
74 new_lf->stream = fopen(name, "w");
75 if (new_lf->stream == NULL) {
76 perror(name);
77 exit(1);
78 }
79 }
80 return new_lf;
81 }
82
83
84 void
85 lf_close(lf *file)
86 {
87 if (file->stream != stdout) {
88 if (fclose(file->stream)) {
89 perror("lf_close.fclose");
90 exit(1);
91 }
92 free(file);
93 }
94 }
95
96
97 int
98 lf_putchr(lf *file,
99 const char chr)
100 {
101 int nr = 0;
102 if (chr == '\n') {
103 file->line_nr += 1;
104 file->line_blank = 1;
105 }
106 else if (file->line_blank) {
107 int pad;
108 for (pad = file->indent; pad > 0; pad--)
109 putc(' ', file->stream);
110 nr += file->indent;
111 file->line_blank = 0;
112 }
113 putc(chr, file->stream);
114 nr += 1;
115 return nr;
116 }
117
118 void
119 lf_indent_suppress(lf *file)
120 {
121 file->line_blank = 0;
122 }
123
124
125 int
126 lf_putstr(lf *file,
127 const char *string)
128 {
129 int nr = 0;
130 const char *chp;
131 if (string != NULL) {
132 for (chp = string; *chp != '\0'; chp++) {
133 nr += lf_putchr(file, *chp);
134 }
135 }
136 return nr;
137 }
138
139 static int
140 do_lf_putunsigned(lf *file,
141 unsigned u)
142 {
143 int nr = 0;
144 if (u > 0) {
145 nr += do_lf_putunsigned(file, u / 10);
146 nr += lf_putchr(file, (u % 10) + '0');
147 }
148 return nr;
149 }
150
151
152 int
153 lf_putint(lf *file,
154 int decimal)
155 {
156 int nr = 0;
157 if (decimal == 0)
158 nr += lf_putchr(file, '0');
159 else if (decimal < 0) {
160 nr += lf_putchr(file, '-');
161 nr += do_lf_putunsigned(file, -decimal);
162 }
163 else if (decimal > 0) {
164 nr += do_lf_putunsigned(file, decimal);
165 }
166 else
167 ASSERT(0);
168 return nr;
169 }
170
171
172 int
173 lf_printf(lf *file,
174 const char *fmt,
175 ...)
176 {
177 int nr = 0;
178 char buf[1024];
179 va_list ap;
180
181 va_start(ap, fmt);
182 vsprintf(buf, fmt, ap);
183 /* FIXME - this is really stuffed but so is vsprintf() on a sun! */
184 ASSERT(strlen(buf) > 0 && strlen(buf) < sizeof(buf));
185 nr += lf_putstr(file, buf);
186 va_end(ap);
187 return nr;
188 }
189
190
191 int
192 lf_print__c_code(lf *file,
193 const char *code)
194 {
195 int nr = 0;
196 const char *chp = code;
197 int in_bit_field = 0;
198 while (*chp != '\0') {
199 if (*chp == '\t')
200 chp++;
201 if (*chp == '#')
202 lf_indent_suppress(file);
203 while (*chp != '\0' && *chp != '\n') {
204 if (chp[0] == '{' && !isspace(chp[1])) {
205 in_bit_field = 1;
206 nr += lf_putchr(file, '_');
207 }
208 else if (in_bit_field && chp[0] == ':') {
209 nr += lf_putchr(file, '_');
210 }
211 else if (in_bit_field && *chp == '}') {
212 nr += lf_putchr(file, '_');
213 in_bit_field = 0;
214 }
215 else {
216 nr += lf_putchr(file, *chp);
217 }
218 chp++;
219 }
220 if (in_bit_field)
221 error("bit field paren miss match some where\n");
222 if (*chp == '\n') {
223 nr += lf_putchr(file, '\n');
224 chp++;
225 }
226 }
227 nr += lf_putchr(file, '\n');
228 return nr;
229 }
230
231
232 int
233 lf_print__external_reference(lf *file,
234 int line_nr,
235 const char *file_name)
236 {
237 int nr = 0;
238 switch (file->references) {
239 case lf_include_references:
240 lf_indent_suppress(file);
241 nr += lf_putstr(file, "#line ");
242 nr += lf_putint(file, line_nr);
243 nr += lf_putstr(file, " \"");
244 nr += lf_putstr(file, file_name);
245 nr += lf_putstr(file, "\"\n");
246 break;
247 case lf_omit_references:
248 break;
249 }
250 return nr;
251 }
252
253 int
254 lf_print__internal_reference(lf *file)
255 {
256 int nr = 0;
257 nr += lf_print__external_reference(file, file->line_nr+2, file->name);
258 /* line_nr == last_line, want to number from next */
259 return nr;
260 }
261
262 void
263 lf_indent(lf *file, int delta)
264 {
265 file->indent += delta;
266 }
267
268
269 int
270 lf_print__gnu_copyleft(lf *file)
271 {
272 int nr = 0;
273 switch (file->type) {
274 case lf_is_c:
275 case lf_is_h:
276 nr += lf_printf(file, "\
277 /* This file is part of the program psim.
278
279 Copyright (C) 1994-1995, Andrew Cagney <cagney@highland.com.au>
280
281 This program is free software; you can redistribute it and/or modify
282 it under the terms of the GNU General Public License as published by
283 the Free Software Foundation; either version 2 of the License, or
284 (at your option) any later version.
285
286 This program is distributed in the hope that it will be useful,
287 but WITHOUT ANY WARRANTY; without even the implied warranty of
288 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
289 GNU General Public License for more details.
290
291 You should have received a copy of the GNU General Public License
292 along with this program; if not, write to the Free Software
293 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
294
295 --
296
297 This file was generated by the program %s */
298 ", filter_filename(file->program));
299 break;
300 default:
301 ASSERT(0);
302 break;
303 }
304 return nr;
305 }
306
307
308 int
309 lf_putbin(lf *file, int decimal, int width)
310 {
311 int nr = 0;
312 int bit;
313 ASSERT(width > 0);
314 for (bit = 1 << (width-1); bit != 0; bit >>= 1) {
315 if (decimal & bit)
316 nr += lf_putchr(file, '1');
317 else
318 nr += lf_putchr(file, '0');
319 }
320 return nr;
321 }
322
323 int
324 lf_print__this_file_is_empty(lf *file)
325 {
326 int nr = 0;
327 switch (file->type) {
328 case lf_is_c:
329 case lf_is_h:
330 nr += lf_printf(file,
331 "/* This generated file (%s) is intentionally left blank */\n",
332 file->name);
333 break;
334 default:
335 ASSERT(0);
336 }
337 return nr;
338 }
339
340 int
341 lf_print__ucase_filename(lf *file)
342 {
343 int nr = 0;
344 const char *chp = file->name;
345 while (*chp != '\0') {
346 char ch = *chp;
347 if (islower(ch)) {
348 nr += lf_putchr(file, toupper(ch));
349 }
350 else if (ch == '.')
351 nr += lf_putchr(file, '_');
352 else
353 nr += lf_putchr(file, ch);
354 chp++;
355 }
356 return nr;
357 }
358
359 int
360 lf_print__file_start(lf *file)
361 {
362 int nr = 0;
363 switch (file->type) {
364 case lf_is_h:
365 case lf_is_c:
366 nr += lf_print__gnu_copyleft(file);
367 nr += lf_printf(file, "\n");
368 nr += lf_printf(file, "#ifndef _");
369 nr += lf_print__ucase_filename(file);
370 nr += lf_printf(file, "_\n");
371 nr += lf_printf(file, "#define _");
372 nr += lf_print__ucase_filename(file);
373 nr += lf_printf(file, "_\n");
374 nr += lf_printf(file, "\n");
375 break;
376 default:
377 ASSERT(0);
378 }
379 return nr;
380 }
381
382
383 int
384 lf_print__file_finish(lf *file)
385 {
386 int nr = 0;
387 switch (file->type) {
388 case lf_is_h:
389 case lf_is_c:
390 nr += lf_printf(file, "\n");
391 nr += lf_printf(file, "#endif /* _");
392 nr += lf_print__ucase_filename(file);
393 nr += lf_printf(file, "_*/\n");
394 break;
395 default:
396 ASSERT(0);
397 }
398 return nr;
399 }
400
401
402 int
403 lf_print_function_type(lf *file,
404 const char *type,
405 const char *prefix,
406 const char *trailing_space)
407 {
408 int nr = 0;
409 nr += lf_printf(file, "%s\\\n(%s)", prefix, type);
410 if (trailing_space != NULL)
411 nr += lf_printf(file, "%s", trailing_space);
412 #if 0
413 const char *type_pointer = strrchr(type, '*');
414 int type_pointer_offset = (type_pointer != NULL
415 ? type_pointer - type
416 : 0);
417 if (type_pointer == NULL) {
418 lf_printf(file, "%s %s", type, prefix);
419 }
420 else {
421 char *munged_type = (char*)zalloc(strlen(type)
422 + strlen(prefix)
423 + strlen(" * ")
424 + 1);
425 strcpy(munged_type, type);
426 munged_type[type_pointer_offset] = '\0';
427 if (type_pointer_offset > 0 && type[type_pointer_offset-1] != ' ')
428 strcat(munged_type, " ");
429 strcat(munged_type, prefix);
430 strcat(munged_type, " ");
431 strcat(munged_type, type + type_pointer_offset);
432 lf_printf(file, "%s", munged_type);
433 free(munged_type);
434 }
435 if (trailing_space != NULL && type_pointer_offset < strlen(type) - 1)
436 lf_printf(file, trailing_space);
437 #endif
438 return nr;
439 }
440