#include <stdio.h>
#include <string.h>
#include <errno.h>
#include "as.h"
#include "input-file.h"
#include "safe-ctype.h"
static int input_file_get (char *, int);
int preprocess = 0;
#define BUFFER_SIZE (32 * 1024)
static FILE *f_in;
static char *file_name;
struct saved_file
{
FILE * f_in;
char * file_name;
int preprocess;
char * app_save;
};
void
input_file_begin (void)
{
f_in = (FILE *) 0;
}
void
input_file_end (void)
{
}
unsigned int
input_file_buffer_size (void)
{
return (BUFFER_SIZE);
}
int
input_file_is_open (void)
{
return f_in != (FILE *) 0;
}
char *
input_file_push (void)
{
register struct saved_file *saved;
saved = (struct saved_file *) xmalloc (sizeof *saved);
saved->f_in = f_in;
saved->file_name = file_name;
saved->preprocess = preprocess;
if (preprocess)
saved->app_save = app_push ();
input_file_begin ();
return (char *) saved;
}
void
input_file_pop (char *arg)
{
register struct saved_file *saved = (struct saved_file *) arg;
input_file_end ();
f_in = saved->f_in;
file_name = saved->file_name;
preprocess = saved->preprocess;
if (preprocess)
app_pop (saved->app_save);
free (arg);
}
void
input_file_open (char *filename,
int pre)
{
int c;
char buf[80];
preprocess = pre;
assert (filename != 0);
if (filename[0])
{
f_in = fopen (filename, FOPEN_RT);
file_name = filename;
}
else
{
f_in = stdin;
file_name = _("{standard input}");
}
if (f_in)
c = getc (f_in);
if (f_in == NULL || ferror (f_in))
{
#ifdef BFD_ASSEMBLER
bfd_set_error (bfd_error_system_call);
#endif
as_perror (_("Can't open %s for reading"), file_name);
if (f_in)
{
fclose (f_in);
f_in = NULL;
}
return;
}
if (c == '#')
{
c = getc (f_in);
if (c == 'N')
{
fgets (buf, 80, f_in);
if (!strncmp (buf, "O_APP", 5) && ISSPACE (buf[5]))
preprocess = 0;
if (!strchr (buf, '\n'))
ungetc ('#', f_in);
else
ungetc ('\n', f_in);
}
else if (c == 'A')
{
fgets (buf, 80, f_in);
if (!strncmp (buf, "PP", 2) && ISSPACE (buf[2]))
preprocess = 1;
if (!strchr (buf, '\n'))
ungetc ('#', f_in);
else
ungetc ('\n', f_in);
}
else if (c == '\n')
ungetc ('\n', f_in);
else
ungetc ('#', f_in);
}
else
ungetc (c, f_in);
}
void
input_file_close (void)
{
if (f_in != NULL)
fclose (f_in);
f_in = 0;
}
static int
input_file_get (char *buf, int buflen)
{
int size;
size = fread (buf, sizeof (char), buflen, f_in);
if (size < 0)
{
#ifdef BFD_ASSEMBLER
bfd_set_error (bfd_error_system_call);
#endif
as_perror (_("Can't read from %s"), file_name);
size = 0;
}
return size;
}
char *
input_file_give_next_buffer (char *where )
{
char *return_value;
register int size;
if (f_in == (FILE *) 0)
return 0;
if (preprocess)
size = do_scrub_chars (input_file_get, where, BUFFER_SIZE);
else
size = fread (where, sizeof (char), BUFFER_SIZE, f_in);
if (size < 0)
{
#ifdef BFD_ASSEMBLER
bfd_set_error (bfd_error_system_call);
#endif
as_perror (_("Can't read from %s"), file_name);
size = 0;
}
if (size)
return_value = where + size;
else
{
if (fclose (f_in))
{
#ifdef BFD_ASSEMBLER
bfd_set_error (bfd_error_system_call);
#endif
as_perror (_("Can't close %s"), file_name);
}
f_in = (FILE *) 0;
return_value = 0;
}
return return_value;
}