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