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/>.
25 #include "build-config.h"
34 int line_nr
; /* nr complete lines written, curr line is line_nr+1 */
37 const char *name
; /* Output name with diagnostics. */
38 const char *filename
; /* Output filename. */
39 char *tmpname
; /* Temporary output filename. */
41 lf_file_references references
;
47 lf_open(const char *name
,
48 const char *real_name
,
49 lf_file_references references
,
53 /* create a file object */
54 lf
*new_lf
= ZALLOC(lf
);
55 ASSERT(new_lf
!= NULL
);
56 new_lf
->references
= references
;
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
;
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
) {
87 /* If we wrote to stdout, no house keeping needed. */
88 if (file
->stream
== stdout
)
91 /* Rename the temp file to the real file if it's changed. */
92 fp
= fopen (file
->filename
, "r");
97 fseek (fp
, 0, SEEK_END
);
100 if (len
== ftell (file
->stream
))
104 char *oldbuf
= zalloc (len
);
105 char *newbuf
= zalloc (len
);
109 while ((cnt
= fread (oldbuf
+ off
, 1, len
- off
, fp
)) > 0)
113 rewind (file
->stream
);
115 while ((cnt
= fread (newbuf
+ off
, 1, len
- off
, file
->stream
)) > 0)
119 if (memcmp (oldbuf
, newbuf
, len
) == 0)
126 if (fclose (file
->stream
))
128 perror ("lf_close.fclose");
134 if (rename (file
->tmpname
, file
->filename
) != 0)
136 perror ("lf_close.rename");
142 if (remove (file
->tmpname
) != 0)
144 perror ("lf_close.unlink");
149 free (file
->tmpname
);
161 file
->line_blank
= 1;
163 else if (file
->line_blank
) {
165 for (pad
= file
->indent
; pad
> 0; pad
--)
166 putc(' ', file
->stream
);
168 file
->line_blank
= 0;
170 putc(chr
, file
->stream
);
176 lf_indent_suppress(lf
*file
)
178 file
->line_blank
= 0;
188 if (string
!= NULL
) {
189 for (chp
= string
; *chp
!= '\0'; chp
++) {
190 nr
+= lf_putchr(file
, *chp
);
197 do_lf_putunsigned(lf
*file
,
202 nr
+= do_lf_putunsigned(file
, u
/ 10);
203 nr
+= lf_putchr(file
, (u
% 10) + '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
);
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
);
249 lf_print__c_code(lf
*file
,
253 const char *chp
= code
;
254 int in_bit_field
= 0;
255 while (*chp
!= '\0') {
259 lf_indent_suppress(file
);
260 while (*chp
!= '\0' && *chp
!= '\n') {
261 if (chp
[0] == '{' && !isspace(chp
[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
, '_');
273 nr
+= lf_putchr(file
, *chp
);
278 error("bit field paren miss match some where\n");
280 nr
+= lf_putchr(file
, '\n');
284 nr
+= lf_putchr(file
, '\n');
290 lf_print__external_reference(lf
*file
,
292 const char *file_name
)
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");
304 case lf_omit_references
:
311 lf_print__internal_reference(lf
*file
)
314 nr
+= lf_print__external_reference(file
, file
->line_nr
+2, file
->name
);
315 /* line_nr == last_line, want to number from next */
320 lf_indent(lf
*file
, int delta
)
322 file
->indent
+= delta
;
327 lf_print__gnu_copyleft(lf
*file
)
330 switch (file
->type
) {
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\
353 This file was generated by the program %s */\n\
354 ", filter_filename(file
->program
));
365 lf_putbin(lf
*file
, int decimal
, int width
)
370 for (bit
= 1 << (width
-1); bit
!= 0; bit
>>= 1) {
372 nr
+= lf_putchr(file
, '1');
374 nr
+= lf_putchr(file
, '0');
380 lf_print__this_file_is_empty(lf
*file
)
383 switch (file
->type
) {
386 nr
+= lf_printf(file
,
387 "/* This generated file (%s) is intentionally left blank */\n",
397 lf_print__ucase_filename(lf
*file
)
400 const char *chp
= file
->name
;
401 while (*chp
!= '\0') {
404 nr
+= lf_putchr(file
, toupper(ch
));
407 nr
+= lf_putchr(file
, '_');
409 nr
+= lf_putchr(file
, ch
);
416 lf_print__file_start(lf
*file
)
419 switch (file
->type
) {
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");
440 lf_print__file_finish(lf
*file
)
443 switch (file
->type
) {
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");
459 lf_print_function_type(lf
*file
,
462 const char *trailing_space
)
465 nr
+= lf_printf(file
, "%s\\\n(%s)", prefix
, type
);
466 if (trailing_space
!= NULL
)
467 nr
+= lf_printf(file
, "%s", trailing_space
);
469 const char *type_pointer
= strrchr(type
, '*');
470 int type_pointer_offset
= (type_pointer
!= NULL
471 ? type_pointer
- type
473 if (type_pointer
== NULL
) {
474 lf_printf(file
, "%s %s", type
, prefix
);
477 char *munged_type
= (char*)zalloc(strlen(type
)
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
);
491 if (trailing_space
!= NULL
&& type_pointer_offset
< strlen(type
) - 1)
492 lf_printf(file
, trailing_space
);