]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - sim/igen/lf.c
Initial creation of sourceware repository
[thirdparty/binutils-gdb.git] / sim / igen / 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 int
119 lf_write (lf *file,
120 const char *string,
121 int strlen_string)
122 {
123 int nr = 0;
124 int i;
125 for (i = 0; i < strlen_string; i++)
126 nr += lf_putchr (file, string[i]);
127 return nr;
128 }
129
130
131 void
132 lf_indent_suppress(lf *file)
133 {
134 file->line_blank = 0;
135 }
136
137
138 int
139 lf_putstr(lf *file,
140 const char *string)
141 {
142 int nr = 0;
143 const char *chp;
144 if (string != NULL) {
145 for (chp = string; *chp != '\0'; chp++) {
146 nr += lf_putchr(file, *chp);
147 }
148 }
149 return nr;
150 }
151
152 static int
153 do_lf_putunsigned(lf *file,
154 unsigned u)
155 {
156 int nr = 0;
157 if (u > 0) {
158 nr += do_lf_putunsigned(file, u / 10);
159 nr += lf_putchr(file, (u % 10) + '0');
160 }
161 return nr;
162 }
163
164
165 int
166 lf_putint(lf *file,
167 int decimal)
168 {
169 int nr = 0;
170 if (decimal == 0)
171 nr += lf_putchr(file, '0');
172 else if (decimal < 0) {
173 nr += lf_putchr(file, '-');
174 nr += do_lf_putunsigned(file, -decimal);
175 }
176 else if (decimal > 0) {
177 nr += do_lf_putunsigned(file, decimal);
178 }
179 else
180 ASSERT(0);
181 return nr;
182 }
183
184
185 int
186 lf_printf (lf *file,
187 const char *fmt,
188 ...)
189 {
190 int nr = 0;
191 char buf[1024];
192 va_list ap;
193
194 va_start (ap, fmt);
195 vsprintf (buf, fmt, ap);
196 /* FIXME - this is really stuffed but so is vsprintf() on a sun! */
197 ASSERT (strlen (buf) < sizeof (buf));
198 nr += lf_putstr (file, buf);
199 va_end(ap);
200 return nr;
201 }
202
203
204 int
205 lf_print__line_ref (lf *file,
206 line_ref *line)
207 {
208 return lf_print__external_ref (file, line->line_nr, line->file_name);
209 }
210
211 int
212 lf_print__external_ref (lf *file,
213 int line_nr,
214 const char *file_name)
215 {
216 int nr = 0;
217 switch (file->references)
218 {
219 case lf_include_references:
220 lf_indent_suppress(file);
221 nr += lf_putstr (file, "#line ");
222 nr += lf_putint (file, line_nr);
223 nr += lf_putstr (file, " \"");
224 nr += lf_putstr (file, file_name);
225 nr += lf_putstr (file, "\"\n");
226 break;
227 case lf_omit_references:
228 nr += lf_putstr (file, "/* ");
229 nr += lf_putstr (file, file_name);
230 nr += lf_putstr (file, ":");
231 nr += lf_putint (file, line_nr);
232 nr += lf_putstr (file, "*/\n");
233 break;
234 }
235 return nr;
236 }
237
238 int
239 lf_print__internal_ref (lf *file)
240 {
241 int nr = 0;
242 nr += lf_print__external_ref (file, file->line_nr+2, file->name);
243 /* line_nr == last_line, want to number from next */
244 return nr;
245 }
246
247 void
248 lf_indent (lf *file, int delta)
249 {
250 file->indent += delta;
251 }
252
253
254 int
255 lf_print__gnu_copyleft (lf *file)
256 {
257 int nr = 0;
258 switch (file->type) {
259 case lf_is_c:
260 case lf_is_h:
261 nr += lf_printf(file, "\
262 /* This file is part of the program psim.
263
264 Copyright (C) 1994-1997, Andrew Cagney <cagney@highland.com.au>
265
266 This program is free software; you can redistribute it and/or modify
267 it under the terms of the GNU General Public License as published by
268 the Free Software Foundation; either version 2 of the License, or
269 (at your option) any later version.
270
271 This program is distributed in the hope that it will be useful,
272 but WITHOUT ANY WARRANTY; without even the implied warranty of
273 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
274 GNU General Public License for more details.
275
276 You should have received a copy of the GNU General Public License
277 along with this program; if not, write to the Free Software
278 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
279
280 --
281
282 This file was generated by the program %s */
283 ", filter_filename(file->program));
284 break;
285 default:
286 ASSERT(0);
287 break;
288 }
289 return nr;
290 }
291
292
293 int
294 lf_putbin(lf *file, int decimal, int width)
295 {
296 int nr = 0;
297 int bit;
298 ASSERT(width > 0);
299 for (bit = 1 << (width-1); bit != 0; bit >>= 1) {
300 if (decimal & bit)
301 nr += lf_putchr(file, '1');
302 else
303 nr += lf_putchr(file, '0');
304 }
305 return nr;
306 }
307
308 int
309 lf_print__this_file_is_empty(lf *file,
310 const char *reason)
311 {
312 int nr = 0;
313 switch (file->type) {
314 case lf_is_c:
315 case lf_is_h:
316 nr += lf_printf (file,
317 "/* This generated file (%s) is intentionally left blank",
318 file->name);
319 if (reason != NULL)
320 nr += lf_printf (file, " - %s", reason);
321 nr += lf_printf (file, " */\n");
322 break;
323 default:
324 ERROR ("Bad switch");
325 }
326 return nr;
327 }
328
329 int
330 lf_print__ucase_filename(lf *file)
331 {
332 int nr = 0;
333 const char *chp = file->name;
334 while (*chp != '\0') {
335 char ch = *chp;
336 if (islower(ch)) {
337 nr += lf_putchr(file, toupper(ch));
338 }
339 else if (ch == '.')
340 nr += lf_putchr(file, '_');
341 else
342 nr += lf_putchr(file, ch);
343 chp++;
344 }
345 return nr;
346 }
347
348 int
349 lf_print__file_start(lf *file)
350 {
351 int nr = 0;
352 switch (file->type) {
353 case lf_is_h:
354 case lf_is_c:
355 nr += lf_print__gnu_copyleft(file);
356 nr += lf_printf(file, "\n");
357 nr += lf_printf(file, "#ifndef ");
358 nr += lf_print__ucase_filename(file);
359 nr += lf_printf(file, "\n");
360 nr += lf_printf(file, "#define ");
361 nr += lf_print__ucase_filename(file);
362 nr += lf_printf(file, "\n");
363 nr += lf_printf(file, "\n");
364 break;
365 default:
366 ASSERT(0);
367 }
368 return nr;
369 }
370
371
372 int
373 lf_print__file_finish(lf *file)
374 {
375 int nr = 0;
376 switch (file->type) {
377 case lf_is_h:
378 case lf_is_c:
379 nr += lf_printf(file, "\n");
380 nr += lf_printf(file, "#endif /* _");
381 nr += lf_print__ucase_filename(file);
382 nr += lf_printf(file, "_*/\n");
383 break;
384 default:
385 ASSERT(0);
386 }
387 return nr;
388 }
389
390
391 int
392 lf_print__function_type (lf *file,
393 const char *type,
394 const char *prefix,
395 const char *trailing_space)
396 {
397 int nr = 0;
398 nr += lf_printf (file, "%s\\\n(%s)", prefix, type);
399 if (trailing_space != NULL)
400 nr += lf_printf (file, "%s", trailing_space);
401 return nr;
402 }
403
404 int
405 lf_print__function_type_function (lf *file,
406 print_function *print_type,
407 const char *prefix,
408 const char *trailing_space)
409 {
410 int nr = 0;
411 nr += lf_printf (file, "%s\\\n(", prefix);
412 nr += print_type (file);
413 nr += lf_printf (file, ")");
414 if (trailing_space != NULL)
415 nr += lf_printf (file, "%s", trailing_space);
416 return nr;
417 }
418