Subversion Repositories Kolibri OS

Rev

Rev 5222 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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