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