1 /* The IGEN simulator generator for GDB, the GNU Debugger.
3 Copyright 2002-2023 Free Software Foundation, Inc.
5 Contributed by Andrew Cagney.
7 This file is part of GDB.
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>. */
37 int line_nr
; /* nr complete lines written, curr line is line_nr+1 */
40 const char *name
; /* Output name with diagnostics. */
41 const char *filename
; /* Output filename. */
42 char *tmpname
; /* Temporary output filename. */
44 lf_file_references references
;
50 lf_open (const char *name
,
51 const char *real_name
,
52 lf_file_references references
,
53 lf_file_type type
, const char *program
)
55 /* create a file object */
56 lf
*new_lf
= ZALLOC (lf
);
57 ASSERT (new_lf
!= NULL
);
58 new_lf
->references
= references
;
60 new_lf
->name
= (real_name
== NULL
? name
: real_name
);
61 new_lf
->filename
= name
;
62 new_lf
->program
= program
;
63 /* attach to stdout if pipe */
64 if (!strcmp (name
, "-"))
66 new_lf
->stream
= stdout
;
70 /* create a new file */
71 char *tmpname
= zalloc (strlen (name
) + 5);
72 sprintf (tmpname
, "%s.tmp", name
);
73 new_lf
->filename
= name
;
74 new_lf
->tmpname
= tmpname
;
75 new_lf
->stream
= fopen (tmpname
, "w+");
76 if (new_lf
->stream
== NULL
)
87 lf_get_file_type (const lf
*file
)
99 /* If we wrote to stdout, no house keeping needed. */
100 if (file
->stream
== stdout
)
103 /* Rename the temp file to the real file if it's changed. */
104 fp
= fopen (file
->filename
, "r");
109 fseek (fp
, 0, SEEK_END
);
112 if (len
== ftell (file
->stream
))
116 char *oldbuf
= zalloc (len
);
117 char *newbuf
= zalloc (len
);
121 while ((cnt
= fread (oldbuf
+ off
, 1, len
- off
, fp
)) > 0)
125 rewind (file
->stream
);
127 while ((cnt
= fread (newbuf
+ off
, 1, len
- off
, file
->stream
)) > 0)
131 if (memcmp (oldbuf
, newbuf
, len
) == 0)
138 if (fclose (file
->stream
))
140 perror ("lf_close.fclose");
146 if (rename (file
->tmpname
, file
->filename
) != 0)
148 perror ("lf_close.rename");
154 if (remove (file
->tmpname
) != 0)
156 perror ("lf_close.unlink");
161 free (file
->tmpname
);
167 lf_putchr (lf
*file
, const char chr
)
173 file
->line_blank
= 1;
175 else if (file
->line_blank
)
178 for (pad
= file
->indent
; pad
> 0; pad
--)
179 putc (' ', file
->stream
);
181 file
->line_blank
= 0;
183 putc (chr
, file
->stream
);
189 lf_write (lf
*file
, const char *string
, int strlen_string
)
193 for (i
= 0; i
< strlen_string
; i
++)
194 nr
+= lf_putchr (file
, string
[i
]);
200 lf_indent_suppress (lf
*file
)
202 file
->line_blank
= 0;
207 lf_putstr (lf
*file
, const char *string
)
213 for (chp
= string
; *chp
!= '\0'; chp
++)
215 nr
+= lf_putchr (file
, *chp
);
222 do_lf_putunsigned (lf
*file
, unsigned u
)
227 nr
+= do_lf_putunsigned (file
, u
/ 10);
228 nr
+= lf_putchr (file
, (u
% 10) + '0');
235 lf_putint (lf
*file
, int decimal
)
239 nr
+= lf_putchr (file
, '0');
240 else if (decimal
< 0)
242 nr
+= lf_putchr (file
, '-');
243 nr
+= do_lf_putunsigned (file
, -decimal
);
245 else if (decimal
> 0)
247 nr
+= do_lf_putunsigned (file
, decimal
);
256 lf_printf (lf
*file
, const char *fmt
, ...)
263 vsprintf (buf
, fmt
, ap
);
264 /* FIXME - this is really stuffed but so is vsprintf() on a sun! */
265 ASSERT (strlen (buf
) < sizeof (buf
));
266 nr
+= lf_putstr (file
, buf
);
273 lf_print__line_ref (lf
*file
, const line_ref
*line
)
275 return lf_print__external_ref (file
, line
->line_nr
, line
->file_name
);
279 lf_print__external_ref (lf
*file
, int line_nr
, const char *file_name
)
282 switch (file
->references
)
284 case lf_include_references
:
285 lf_indent_suppress (file
);
286 nr
+= lf_putstr (file
, "#line ");
287 nr
+= lf_putint (file
, line_nr
);
288 nr
+= lf_putstr (file
, " \"");
289 nr
+= lf_putstr (file
, file_name
);
290 nr
+= lf_putstr (file
, "\"\n");
292 case lf_omit_references
:
293 nr
+= lf_putstr (file
, "/* ");
294 nr
+= lf_putstr (file
, file_name
);
295 nr
+= lf_putstr (file
, ":");
296 nr
+= lf_putint (file
, line_nr
);
297 nr
+= lf_putstr (file
, "*/\n");
304 lf_print__internal_ref (lf
*file
)
307 nr
+= lf_print__external_ref (file
, file
->line_nr
+ 2, file
->name
);
308 /* line_nr == last_line, want to number from next */
313 lf_indent (lf
*file
, int delta
)
315 file
->indent
+= delta
;
320 lf_print__gnu_copyleft (lf
*file
)
327 nr
+= lf_printf (file
, "\
328 /* This file is part of GDB.\n\
330 Copyright 2002, 2007 Free Software Foundation, Inc.\n\
332 This program is free software; you can redistribute it and/or modify\n\
333 it under the terms of the GNU General Public License as published by\n\
334 the Free Software Foundation; either version 3 of the License, or\n\
335 (at your option) any later version.\n\
337 This program is distributed in the hope that it will be useful,\n\
338 but WITHOUT ANY WARRANTY; without even the implied warranty of\n\
339 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n\
340 GNU General Public License for more details.\n\
342 You should have received a copy of the GNU General Public License\n\
343 along with this program. If not, see <http://www.gnu.org/licenses/>.\n\
347 This file was generated by the program %s */\n\
348 ", filter_filename (file
->program
));
359 lf_putbin (lf
*file
, int decimal
, int width
)
364 for (bit
= 1 << (width
- 1); bit
!= 0; bit
>>= 1)
367 nr
+= lf_putchr (file
, '1');
369 nr
+= lf_putchr (file
, '0');
375 lf_print__this_file_is_empty (lf
*file
, const char *reason
)
382 nr
+= lf_printf (file
,
383 "/* This generated file (%s) is intentionally left blank",
386 nr
+= lf_printf (file
, " - %s", reason
);
387 nr
+= lf_printf (file
, " */\n");
390 ERROR ("Bad switch");
396 lf_print__ucase_filename (lf
*file
)
399 const char *chp
= file
->name
;
405 nr
+= lf_putchr (file
, toupper (ch
));
408 nr
+= lf_putchr (file
, '_');
410 nr
+= lf_putchr (file
, ch
);
417 lf_print__file_start (lf
*file
)
424 nr
+= lf_print__gnu_copyleft (file
);
425 nr
+= lf_printf (file
, "\n");
426 nr
+= lf_printf (file
, "#ifndef ");
427 nr
+= lf_print__ucase_filename (file
);
428 nr
+= lf_printf (file
, "\n");
429 nr
+= lf_printf (file
, "#define ");
430 nr
+= lf_print__ucase_filename (file
);
431 nr
+= lf_printf (file
, "\n");
432 nr
+= lf_printf (file
, "\n");
442 lf_print__file_finish (lf
*file
)
449 nr
+= lf_printf (file
, "\n");
450 nr
+= lf_printf (file
, "#endif /* _");
451 nr
+= lf_print__ucase_filename (file
);
452 nr
+= lf_printf (file
, "_*/\n");
462 lf_print__function_type (lf
*file
,
464 const char *prefix
, const char *trailing_space
)
467 nr
+= lf_printf (file
, "%s\\\n(%s)", prefix
, type
);
468 if (trailing_space
!= NULL
)
469 nr
+= lf_printf (file
, "%s", trailing_space
);
474 lf_print__function_type_function (lf
*file
,
475 print_function
* print_type
,
477 const char *trailing_space
)
480 nr
+= lf_printf (file
, "%s\\\n(", prefix
);
481 nr
+= print_type (file
);
482 nr
+= lf_printf (file
, ")");
483 if (trailing_space
!= NULL
)
484 nr
+= lf_printf (file
, "%s", trailing_space
);