Fix whitespace snafu in tc-riscv.c
[binutils-gdb.git] / sim / ppc / lf.c
blobe170a47b0902f2897d8ff5a74f2d0893b6302039
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/>.
20 #include <stdbool.h>
21 #include <stdio.h>
22 #include <stdarg.h>
23 #include <ctype.h>
25 #include "build-config.h"
26 #include "misc.h"
27 #include "lf.h"
29 #include <stdlib.h>
30 #include <string.h>
32 struct _lf {
33 FILE *stream;
34 int line_nr; /* nr complete lines written, curr line is line_nr+1 */
35 int indent;
36 int line_blank;
37 const char *name; /* Output name with diagnostics. */
38 const char *filename; /* Output filename. */
39 char *tmpname; /* Temporary output filename. */
40 const char *program;
41 lf_file_references references;
42 lf_file_type type;
46 lf *
47 lf_open(const char *name,
48 const char *real_name,
49 lf_file_references references,
50 lf_file_type type,
51 const char *program)
53 /* create a file object */
54 lf *new_lf = ZALLOC(lf);
55 ASSERT(new_lf != NULL);
56 new_lf->references = references;
57 new_lf->type = type;
58 new_lf->name = (real_name == NULL ? name : real_name);
59 new_lf->filename = name;
60 new_lf->program = program;
61 /* attach to stdout if pipe */
62 if (!strcmp(name, "-")) {
63 new_lf->stream = stdout;
65 else {
66 /* create a new file */
67 char *tmpname = zalloc (strlen (name) + 5);
68 sprintf (tmpname, "%s.tmp", name);
69 new_lf->filename = name;
70 new_lf->tmpname = tmpname;
71 new_lf->stream = fopen(tmpname, "w+");
72 if (new_lf->stream == NULL) {
73 perror(name);
74 exit(1);
77 return new_lf;
81 void
82 lf_close(lf *file)
84 FILE *fp;
85 bool update = true;
87 /* If we wrote to stdout, no house keeping needed. */
88 if (file->stream == stdout)
89 return;
91 /* Rename the temp file to the real file if it's changed. */
92 fp = fopen (file->filename, "r");
93 if (fp != NULL)
95 off_t len;
97 fseek (fp, 0, SEEK_END);
98 len = ftell (fp);
100 if (len == ftell (file->stream))
102 off_t off;
103 size_t cnt;
104 char *oldbuf = zalloc (len);
105 char *newbuf = zalloc (len);
107 rewind (fp);
108 off = 0;
109 while ((cnt = fread (oldbuf + off, 1, len - off, fp)) > 0)
110 off += cnt;
111 ASSERT (off == len);
113 rewind (file->stream);
114 off = 0;
115 while ((cnt = fread (newbuf + off, 1, len - off, file->stream)) > 0)
116 off += cnt;
117 ASSERT (off == len);
119 if (memcmp (oldbuf, newbuf, len) == 0)
120 update = false;
123 fclose (fp);
126 if (fclose (file->stream))
128 perror ("lf_close.fclose");
129 exit (1);
132 if (update)
134 if (rename (file->tmpname, file->filename) != 0)
136 perror ("lf_close.rename");
137 exit (1);
140 else
142 if (remove (file->tmpname) != 0)
144 perror ("lf_close.unlink");
145 exit (1);
149 free (file->tmpname);
150 free (file);
155 lf_putchr(lf *file,
156 const char chr)
158 int nr = 0;
159 if (chr == '\n') {
160 file->line_nr += 1;
161 file->line_blank = 1;
163 else if (file->line_blank) {
164 int pad;
165 for (pad = file->indent; pad > 0; pad--)
166 putc(' ', file->stream);
167 nr += file->indent;
168 file->line_blank = 0;
170 putc(chr, file->stream);
171 nr += 1;
172 return nr;
175 void
176 lf_indent_suppress(lf *file)
178 file->line_blank = 0;
183 lf_putstr(lf *file,
184 const char *string)
186 int nr = 0;
187 const char *chp;
188 if (string != NULL) {
189 for (chp = string; *chp != '\0'; chp++) {
190 nr += lf_putchr(file, *chp);
193 return nr;
196 static int
197 do_lf_putunsigned(lf *file,
198 unsigned u)
200 int nr = 0;
201 if (u > 0) {
202 nr += do_lf_putunsigned(file, u / 10);
203 nr += lf_putchr(file, (u % 10) + '0');
205 return nr;
210 lf_putint(lf *file,
211 int decimal)
213 int nr = 0;
214 if (decimal == 0)
215 nr += lf_putchr(file, '0');
216 else if (decimal < 0) {
217 nr += lf_putchr(file, '-');
218 nr += do_lf_putunsigned(file, -decimal);
220 else if (decimal > 0) {
221 nr += do_lf_putunsigned(file, decimal);
223 else
224 ASSERT(0);
225 return nr;
230 lf_printf(lf *file,
231 const char *fmt,
232 ...)
234 int nr = 0;
235 char buf[1024];
236 va_list ap;
238 va_start(ap, fmt);
239 vsprintf(buf, fmt, ap);
240 /* FIXME - this is really stuffed but so is vsprintf() on a sun! */
241 ASSERT(strlen(buf) > 0 && strlen(buf) < sizeof(buf));
242 nr += lf_putstr(file, buf);
243 va_end(ap);
244 return nr;
249 lf_print__c_code(lf *file,
250 const char *code)
252 int nr = 0;
253 const char *chp = code;
254 int in_bit_field = 0;
255 while (*chp != '\0') {
256 if (*chp == '\t')
257 chp++;
258 if (*chp == '#')
259 lf_indent_suppress(file);
260 while (*chp != '\0' && *chp != '\n') {
261 if (chp[0] == '{' && !isspace(chp[1])) {
262 in_bit_field = 1;
263 nr += lf_putchr(file, '_');
265 else if (in_bit_field && chp[0] == ':') {
266 nr += lf_putchr(file, '_');
268 else if (in_bit_field && *chp == '}') {
269 nr += lf_putchr(file, '_');
270 in_bit_field = 0;
272 else {
273 nr += lf_putchr(file, *chp);
275 chp++;
277 if (in_bit_field)
278 error("bit field paren miss match some where\n");
279 if (*chp == '\n') {
280 nr += lf_putchr(file, '\n');
281 chp++;
284 nr += lf_putchr(file, '\n');
285 return nr;
290 lf_print__external_reference(lf *file,
291 int line_nr,
292 const char *file_name)
294 int nr = 0;
295 switch (file->references) {
296 case lf_include_references:
297 lf_indent_suppress(file);
298 nr += lf_putstr(file, "#line ");
299 nr += lf_putint(file, line_nr);
300 nr += lf_putstr(file, " \"");
301 nr += lf_putstr(file, file_name);
302 nr += lf_putstr(file, "\"\n");
303 break;
304 case lf_omit_references:
305 break;
307 return nr;
311 lf_print__internal_reference(lf *file)
313 int nr = 0;
314 nr += lf_print__external_reference(file, file->line_nr+2, file->name);
315 /* line_nr == last_line, want to number from next */
316 return nr;
319 void
320 lf_indent(lf *file, int delta)
322 file->indent += delta;
327 lf_print__gnu_copyleft(lf *file)
329 int nr = 0;
330 switch (file->type) {
331 case lf_is_c:
332 case lf_is_h:
333 nr += lf_printf(file, "\n\
334 /* This file is part of the program psim.\n\
336 Copyright (C) 1994-1995, Andrew Cagney <cagney@highland.com.au>\n\
338 This program is free software; you can redistribute it and/or modify\n\
339 it under the terms of the GNU General Public License as published by\n\
340 the Free Software Foundation; either version 3 of the License, or\n\
341 (at your option) any later version.\n\
343 This program is distributed in the hope that it will be useful,\n\
344 but WITHOUT ANY WARRANTY; without even the implied warranty of\n\
345 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n\
346 GNU General Public License for more details.\n\
348 You should have received a copy of the GNU General Public License\n\
349 along with this program; if not, see <http://www.gnu.org/licenses/>.\n\
351 --\n\
353 This file was generated by the program %s */\n\
354 ", filter_filename(file->program));
355 break;
356 default:
357 ASSERT(0);
358 break;
360 return nr;
365 lf_putbin(lf *file, int decimal, int width)
367 int nr = 0;
368 int bit;
369 ASSERT(width > 0);
370 for (bit = 1 << (width-1); bit != 0; bit >>= 1) {
371 if (decimal & bit)
372 nr += lf_putchr(file, '1');
373 else
374 nr += lf_putchr(file, '0');
376 return nr;
380 lf_print__this_file_is_empty(lf *file)
382 int nr = 0;
383 switch (file->type) {
384 case lf_is_c:
385 case lf_is_h:
386 nr += lf_printf(file,
387 "/* This generated file (%s) is intentionally left blank */\n",
388 file->name);
389 break;
390 default:
391 ASSERT(0);
393 return nr;
397 lf_print__ucase_filename(lf *file)
399 int nr = 0;
400 const char *chp = file->name;
401 while (*chp != '\0') {
402 char ch = *chp;
403 if (islower(ch)) {
404 nr += lf_putchr(file, toupper(ch));
406 else if (ch == '.')
407 nr += lf_putchr(file, '_');
408 else
409 nr += lf_putchr(file, ch);
410 chp++;
412 return nr;
416 lf_print__file_start(lf *file)
418 int nr = 0;
419 switch (file->type) {
420 case lf_is_h:
421 case lf_is_c:
422 nr += lf_print__gnu_copyleft(file);
423 nr += lf_printf(file, "\n");
424 nr += lf_printf(file, "#ifndef _");
425 nr += lf_print__ucase_filename(file);
426 nr += lf_printf(file, "_\n");
427 nr += lf_printf(file, "#define _");
428 nr += lf_print__ucase_filename(file);
429 nr += lf_printf(file, "_\n");
430 nr += lf_printf(file, "\n");
431 break;
432 default:
433 ASSERT(0);
435 return nr;
440 lf_print__file_finish(lf *file)
442 int nr = 0;
443 switch (file->type) {
444 case lf_is_h:
445 case lf_is_c:
446 nr += lf_printf(file, "\n");
447 nr += lf_printf(file, "#endif /* _");
448 nr += lf_print__ucase_filename(file);
449 nr += lf_printf(file, "_*/\n");
450 break;
451 default:
452 ASSERT(0);
454 return nr;
459 lf_print_function_type(lf *file,
460 const char *type,
461 const char *prefix,
462 const char *trailing_space)
464 int nr = 0;
465 nr += lf_printf(file, "%s\\\n(%s)", prefix, type);
466 if (trailing_space != NULL)
467 nr += lf_printf(file, "%s", trailing_space);
468 #if 0
469 const char *type_pointer = strrchr(type, '*');
470 int type_pointer_offset = (type_pointer != NULL
471 ? type_pointer - type
472 : 0);
473 if (type_pointer == NULL) {
474 lf_printf(file, "%s %s", type, prefix);
476 else {
477 char *munged_type = (char*)zalloc(strlen(type)
478 + strlen(prefix)
479 + strlen(" * ")
480 + 1);
481 strcpy(munged_type, type);
482 munged_type[type_pointer_offset] = '\0';
483 if (type_pointer_offset > 0 && type[type_pointer_offset-1] != ' ')
484 strcat(munged_type, " ");
485 strcat(munged_type, prefix);
486 strcat(munged_type, " ");
487 strcat(munged_type, type + type_pointer_offset);
488 lf_printf(file, "%s", munged_type);
489 free(munged_type);
491 if (trailing_space != NULL && type_pointer_offset < strlen(type) - 1)
492 lf_printf(file, trailing_space);
493 #endif
494 return nr;