1*3d8817e4Smiod /* input_file.c - Deal with Input Files -
2*3d8817e4Smiod Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1999, 2000, 2001,
3*3d8817e4Smiod 2002, 2003, 2005
4*3d8817e4Smiod Free Software Foundation, Inc.
5*3d8817e4Smiod
6*3d8817e4Smiod This file is part of GAS, the GNU Assembler.
7*3d8817e4Smiod
8*3d8817e4Smiod GAS is free software; you can redistribute it and/or modify
9*3d8817e4Smiod it under the terms of the GNU General Public License as published by
10*3d8817e4Smiod the Free Software Foundation; either version 2, or (at your option)
11*3d8817e4Smiod any later version.
12*3d8817e4Smiod
13*3d8817e4Smiod GAS is distributed in the hope that it will be useful,
14*3d8817e4Smiod but WITHOUT ANY WARRANTY; without even the implied warranty of
15*3d8817e4Smiod MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16*3d8817e4Smiod GNU General Public License for more details.
17*3d8817e4Smiod
18*3d8817e4Smiod You should have received a copy of the GNU General Public License
19*3d8817e4Smiod along with GAS; see the file COPYING. If not, write to the Free
20*3d8817e4Smiod Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
21*3d8817e4Smiod 02110-1301, USA. */
22*3d8817e4Smiod
23*3d8817e4Smiod /* Confines all details of reading source bytes to this module.
24*3d8817e4Smiod All O/S specific crocks should live here.
25*3d8817e4Smiod What we lose in "efficiency" we gain in modularity.
26*3d8817e4Smiod Note we don't need to #include the "as.h" file. No common coupling! */
27*3d8817e4Smiod
28*3d8817e4Smiod #include <stdio.h>
29*3d8817e4Smiod #include <string.h>
30*3d8817e4Smiod #include <errno.h>
31*3d8817e4Smiod #include "as.h"
32*3d8817e4Smiod #include "input-file.h"
33*3d8817e4Smiod #include "safe-ctype.h"
34*3d8817e4Smiod
35*3d8817e4Smiod static int input_file_get (char *, int);
36*3d8817e4Smiod
37*3d8817e4Smiod /* This variable is non-zero if the file currently being read should be
38*3d8817e4Smiod preprocessed by app. It is zero if the file can be read straight in. */
39*3d8817e4Smiod int preprocess = 0;
40*3d8817e4Smiod
41*3d8817e4Smiod /* This code opens a file, then delivers BUFFER_SIZE character
42*3d8817e4Smiod chunks of the file on demand.
43*3d8817e4Smiod BUFFER_SIZE is supposed to be a number chosen for speed.
44*3d8817e4Smiod The caller only asks once what BUFFER_SIZE is, and asks before
45*3d8817e4Smiod the nature of the input files (if any) is known. */
46*3d8817e4Smiod
47*3d8817e4Smiod #define BUFFER_SIZE (32 * 1024)
48*3d8817e4Smiod
49*3d8817e4Smiod /* We use static data: the data area is not sharable. */
50*3d8817e4Smiod
51*3d8817e4Smiod static FILE *f_in;
52*3d8817e4Smiod static char *file_name;
53*3d8817e4Smiod
54*3d8817e4Smiod /* Struct for saving the state of this module for file includes. */
55*3d8817e4Smiod struct saved_file
56*3d8817e4Smiod {
57*3d8817e4Smiod FILE * f_in;
58*3d8817e4Smiod char * file_name;
59*3d8817e4Smiod int preprocess;
60*3d8817e4Smiod char * app_save;
61*3d8817e4Smiod };
62*3d8817e4Smiod
63*3d8817e4Smiod /* These hooks accommodate most operating systems. */
64*3d8817e4Smiod
65*3d8817e4Smiod void
input_file_begin(void)66*3d8817e4Smiod input_file_begin (void)
67*3d8817e4Smiod {
68*3d8817e4Smiod f_in = (FILE *) 0;
69*3d8817e4Smiod }
70*3d8817e4Smiod
71*3d8817e4Smiod void
input_file_end(void)72*3d8817e4Smiod input_file_end (void)
73*3d8817e4Smiod {
74*3d8817e4Smiod }
75*3d8817e4Smiod
76*3d8817e4Smiod /* Return BUFFER_SIZE. */
77*3d8817e4Smiod unsigned int
input_file_buffer_size(void)78*3d8817e4Smiod input_file_buffer_size (void)
79*3d8817e4Smiod {
80*3d8817e4Smiod return (BUFFER_SIZE);
81*3d8817e4Smiod }
82*3d8817e4Smiod
83*3d8817e4Smiod /* Push the state of our input, returning a pointer to saved info that
84*3d8817e4Smiod can be restored with input_file_pop (). */
85*3d8817e4Smiod
86*3d8817e4Smiod char *
input_file_push(void)87*3d8817e4Smiod input_file_push (void)
88*3d8817e4Smiod {
89*3d8817e4Smiod register struct saved_file *saved;
90*3d8817e4Smiod
91*3d8817e4Smiod saved = (struct saved_file *) xmalloc (sizeof *saved);
92*3d8817e4Smiod
93*3d8817e4Smiod saved->f_in = f_in;
94*3d8817e4Smiod saved->file_name = file_name;
95*3d8817e4Smiod saved->preprocess = preprocess;
96*3d8817e4Smiod if (preprocess)
97*3d8817e4Smiod saved->app_save = app_push ();
98*3d8817e4Smiod
99*3d8817e4Smiod /* Initialize for new file. */
100*3d8817e4Smiod input_file_begin ();
101*3d8817e4Smiod
102*3d8817e4Smiod return (char *) saved;
103*3d8817e4Smiod }
104*3d8817e4Smiod
105*3d8817e4Smiod void
input_file_pop(char * arg)106*3d8817e4Smiod input_file_pop (char *arg)
107*3d8817e4Smiod {
108*3d8817e4Smiod register struct saved_file *saved = (struct saved_file *) arg;
109*3d8817e4Smiod
110*3d8817e4Smiod input_file_end (); /* Close out old file. */
111*3d8817e4Smiod
112*3d8817e4Smiod f_in = saved->f_in;
113*3d8817e4Smiod file_name = saved->file_name;
114*3d8817e4Smiod preprocess = saved->preprocess;
115*3d8817e4Smiod if (preprocess)
116*3d8817e4Smiod app_pop (saved->app_save);
117*3d8817e4Smiod
118*3d8817e4Smiod free (arg);
119*3d8817e4Smiod }
120*3d8817e4Smiod
121*3d8817e4Smiod void
input_file_open(char * filename,int pre)122*3d8817e4Smiod input_file_open (char *filename, /* "" means use stdin. Must not be 0. */
123*3d8817e4Smiod int pre)
124*3d8817e4Smiod {
125*3d8817e4Smiod int c;
126*3d8817e4Smiod char buf[80];
127*3d8817e4Smiod
128*3d8817e4Smiod preprocess = pre;
129*3d8817e4Smiod
130*3d8817e4Smiod assert (filename != 0); /* Filename may not be NULL. */
131*3d8817e4Smiod if (filename[0])
132*3d8817e4Smiod {
133*3d8817e4Smiod f_in = fopen (filename, FOPEN_RT);
134*3d8817e4Smiod file_name = filename;
135*3d8817e4Smiod }
136*3d8817e4Smiod else
137*3d8817e4Smiod {
138*3d8817e4Smiod /* Use stdin for the input file. */
139*3d8817e4Smiod f_in = stdin;
140*3d8817e4Smiod /* For error messages. */
141*3d8817e4Smiod file_name = _("{standard input}");
142*3d8817e4Smiod }
143*3d8817e4Smiod
144*3d8817e4Smiod if (f_in == NULL)
145*3d8817e4Smiod {
146*3d8817e4Smiod bfd_set_error (bfd_error_system_call);
147*3d8817e4Smiod as_perror (_("Can't open %s for reading"), file_name);
148*3d8817e4Smiod return;
149*3d8817e4Smiod }
150*3d8817e4Smiod
151*3d8817e4Smiod c = getc (f_in);
152*3d8817e4Smiod
153*3d8817e4Smiod if (ferror (f_in))
154*3d8817e4Smiod {
155*3d8817e4Smiod bfd_set_error (bfd_error_system_call);
156*3d8817e4Smiod as_perror (_("Can't open %s for reading"), file_name);
157*3d8817e4Smiod
158*3d8817e4Smiod fclose (f_in);
159*3d8817e4Smiod f_in = NULL;
160*3d8817e4Smiod return;
161*3d8817e4Smiod }
162*3d8817e4Smiod
163*3d8817e4Smiod if (c == '#')
164*3d8817e4Smiod {
165*3d8817e4Smiod /* Begins with comment, may not want to preprocess. */
166*3d8817e4Smiod c = getc (f_in);
167*3d8817e4Smiod if (c == 'N')
168*3d8817e4Smiod {
169*3d8817e4Smiod fgets (buf, 80, f_in);
170*3d8817e4Smiod if (!strncmp (buf, "O_APP", 5) && ISSPACE (buf[5]))
171*3d8817e4Smiod preprocess = 0;
172*3d8817e4Smiod if (!strchr (buf, '\n'))
173*3d8817e4Smiod ungetc ('#', f_in); /* It was longer. */
174*3d8817e4Smiod else
175*3d8817e4Smiod ungetc ('\n', f_in);
176*3d8817e4Smiod }
177*3d8817e4Smiod else if (c == 'A')
178*3d8817e4Smiod {
179*3d8817e4Smiod fgets (buf, 80, f_in);
180*3d8817e4Smiod if (!strncmp (buf, "PP", 2) && ISSPACE (buf[2]))
181*3d8817e4Smiod preprocess = 1;
182*3d8817e4Smiod if (!strchr (buf, '\n'))
183*3d8817e4Smiod ungetc ('#', f_in);
184*3d8817e4Smiod else
185*3d8817e4Smiod ungetc ('\n', f_in);
186*3d8817e4Smiod }
187*3d8817e4Smiod else if (c == '\n')
188*3d8817e4Smiod ungetc ('\n', f_in);
189*3d8817e4Smiod else
190*3d8817e4Smiod ungetc ('#', f_in);
191*3d8817e4Smiod }
192*3d8817e4Smiod else
193*3d8817e4Smiod ungetc (c, f_in);
194*3d8817e4Smiod }
195*3d8817e4Smiod
196*3d8817e4Smiod /* Close input file. */
197*3d8817e4Smiod
198*3d8817e4Smiod void
input_file_close(void)199*3d8817e4Smiod input_file_close (void)
200*3d8817e4Smiod {
201*3d8817e4Smiod /* Don't close a null file pointer. */
202*3d8817e4Smiod if (f_in != NULL)
203*3d8817e4Smiod fclose (f_in);
204*3d8817e4Smiod
205*3d8817e4Smiod f_in = 0;
206*3d8817e4Smiod }
207*3d8817e4Smiod
208*3d8817e4Smiod /* This function is passed to do_scrub_chars. */
209*3d8817e4Smiod
210*3d8817e4Smiod static int
input_file_get(char * buf,int buflen)211*3d8817e4Smiod input_file_get (char *buf, int buflen)
212*3d8817e4Smiod {
213*3d8817e4Smiod int size;
214*3d8817e4Smiod
215*3d8817e4Smiod size = fread (buf, sizeof (char), buflen, f_in);
216*3d8817e4Smiod if (size < 0)
217*3d8817e4Smiod {
218*3d8817e4Smiod bfd_set_error (bfd_error_system_call);
219*3d8817e4Smiod as_perror (_("Can't read from %s"), file_name);
220*3d8817e4Smiod size = 0;
221*3d8817e4Smiod }
222*3d8817e4Smiod return size;
223*3d8817e4Smiod }
224*3d8817e4Smiod
225*3d8817e4Smiod /* Read a buffer from the input file. */
226*3d8817e4Smiod
227*3d8817e4Smiod char *
input_file_give_next_buffer(char * where)228*3d8817e4Smiod input_file_give_next_buffer (char *where /* Where to place 1st character of new buffer. */)
229*3d8817e4Smiod {
230*3d8817e4Smiod char *return_value; /* -> Last char of what we read, + 1. */
231*3d8817e4Smiod register int size;
232*3d8817e4Smiod
233*3d8817e4Smiod if (f_in == (FILE *) 0)
234*3d8817e4Smiod return 0;
235*3d8817e4Smiod /* fflush (stdin); could be done here if you want to synchronise
236*3d8817e4Smiod stdin and stdout, for the case where our input file is stdin.
237*3d8817e4Smiod Since the assembler shouldn't do any output to stdout, we
238*3d8817e4Smiod don't bother to synch output and input. */
239*3d8817e4Smiod if (preprocess)
240*3d8817e4Smiod size = do_scrub_chars (input_file_get, where, BUFFER_SIZE);
241*3d8817e4Smiod else
242*3d8817e4Smiod size = fread (where, sizeof (char), BUFFER_SIZE, f_in);
243*3d8817e4Smiod if (size < 0)
244*3d8817e4Smiod {
245*3d8817e4Smiod bfd_set_error (bfd_error_system_call);
246*3d8817e4Smiod as_perror (_("Can't read from %s"), file_name);
247*3d8817e4Smiod size = 0;
248*3d8817e4Smiod }
249*3d8817e4Smiod if (size)
250*3d8817e4Smiod return_value = where + size;
251*3d8817e4Smiod else
252*3d8817e4Smiod {
253*3d8817e4Smiod if (fclose (f_in))
254*3d8817e4Smiod {
255*3d8817e4Smiod bfd_set_error (bfd_error_system_call);
256*3d8817e4Smiod as_perror (_("Can't close %s"), file_name);
257*3d8817e4Smiod }
258*3d8817e4Smiod f_in = (FILE *) 0;
259*3d8817e4Smiod return_value = 0;
260*3d8817e4Smiod }
261*3d8817e4Smiod
262*3d8817e4Smiod return return_value;
263*3d8817e4Smiod }
264