* This code is derived from software copyrighted by the Free Software
* Modified 1991 by Donn Seeley at UUNET Technologies, Inc.
static char sccsid
[] = "@(#)input-file.c 6.2 (Berkeley) 5/8/91";
/* input_file.c - Deal with Input Files -
Copyright (C) 1987 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
GAS is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
GAS is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GAS; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
* Confines all details of reading source bytes to this module.
* All O/S specific crocks should live here.
* What we lose in "efficiency" we gain in modularity.
* Note we don't need to #include the "as.h" file. No common coupling!
#define NDEBUG /* JF remove asserts */
/* JF: What's the difference between _IOLBF and _IOFBF ? */
#define setbuffer(stream, buf, size) setvbuf((stream), (buf), _IOFBF, (size))
/* #include <sys/types.h>
/* This variable is non-zero if the file currently being read should be
preprocessed by app. It is zero if the file can be read straight in.
* This code opens a file, then delivers BUFFER_SIZE character
* chunks of the file on demand.
* BUFFER_SIZE is supposed to be a number chosen for speed.
* The caller only asks once what BUFFER_SIZE is, and asks before
* the nature of the input files (if any) is known.
#define BUFFER_SIZE (32 * 1024)
static char in_buf
[BUFFER_SIZE
];
* We use static data: the data area is not sharable.
FILE *f_in
; /* JF do things the RIGHT way */
/* static JF remove static so app.c can use file_name */
/* These hooks accomodate most operating systems. */
int /* Return BUFFER_SIZE. */
input_file_buffer_size ()
/* return (file_handle >= 0); */
#ifdef DONTDEF /* JF save old version in case we need it */
input_file_open (filename
, preprocess
, debugging
)
char * filename
; /* "" means use stdin. Must not be 0. */
int preprocess
; /* TRUE if needs app. */
int debugging
; /* TRUE if we are debugging assembler. */
assert( filename
!= 0 ); /* Filename may not be NULL. */
{ /* We have a file name. Suck it and see. */
file_handle
= open (filename
, O_RDONLY
, 0);
{ /* use stdin for the input file. */
file_handle
= fileno (stdin
);
file_name
= "{standard input}"; /* For error messages. */
as_perror ("Can't open %s for reading", file_name
);
* This code was written in haste for a frobbed BSD 4.2.
* I have a flight to catch: will someone please do proper
char temporary_file_name
[12];
(void)strcpy (temporary_file_name
, "#appXXXXXX");
(void)mktemp (temporary_file_name
);
as_perror ("Vfork failed", file_name
);
(void)dup2 (file_handle
, fileno(stdin
));
fd
= open (temporary_file_name
, O_WRONLY
+ O_TRUNC
+ O_CREAT
, 0666);
(void)write(2,"Can't open temporary\n",21);
(void)dup2 (fd
, fileno(stdout
));
/* JF for testing #define PREPROCESSOR "/lib/app" */
#define PREPROCESSOR "./app"
execl (PREPROCESSOR
, PREPROCESSOR
, 0);
(void)write(2,"Exec of app failed. Get help.\n",31);
(void)unlink(temporary_file_name
);
if (status
.w_status
& 0xFF00) /* JF was 0xF000, was wrong */
as_warn( "Can't preprocess file \"%s\", status = %xx", file_name
, status
.w_status
);
file_handle
= open (temporary_file_name
, O_RDONLY
, 0);
if ( ! debugging
&& unlink(temporary_file_name
))
as_perror ("Can't delete temp file %s", temporary_file_name
);
as_perror ("Can't retrieve temp file %s", temporary_file_name
);
input_file_open (filename
,pre
)
char * filename
; /* "" means use stdin. Must not be 0. */
assert( filename
!= 0 ); /* Filename may not be NULL. */
if (filename
[0]) { /* We have a file name. Suck it and see. */
f_in
=fopen(filename
,"r");
} else { /* use stdin for the input file. */
file_name
= "{standard input}"; /* For error messages. */
as_perror ("Can't open %s for reading", file_name
);
setbuffer(f_in
,in_buf
,BUFFER_SIZE
);
if(c
=='#') { /* Begins with comment, may not want to preprocess */
if(!strcmp(buf
,"O_APP\n"))
ungetc('#',f_in
); /* It was longer */
char temporary_file_name
[17];
(void)strcpy (temporary_file_name
, "/tmp/#appXXXXXX");
(void)mktemp (temporary_file_name
);
f_out
=fopen(temporary_file_name
,"w+");
as_perror("Can't open temp file %s",temporary_file_name
);
/* JF this will have to be moved on any system that
does not support removal of open files. */
(void)unlink(temporary_file_name
);/* JF do it NOW */
(void)fclose(f_in
); /* All done with it */
input_file_give_next_buffer (where
)
char * where
; /* Where to place 1st character of new buffer. */
char * return_value
; /* -> Last char of what we read, + 1. */
* fflush (stdin); could be done here if you want to synchronise
* stdin and stdout, for the case where our input file is stdin.
* Since the assembler shouldn't do any output to stdout, we
* don't bother to synch output and input.
/* size = read (file_handle, where, BUFFER_SIZE); */
int do_scrub_next_char();
for(p
=where
,n
=BUFFER_SIZE
;n
;--n
) {
ch
=do_scrub_next_char(scrub_from_file
,scrub_to_file
);
size
= fread(where
,sizeof(char),BUFFER_SIZE
,f_in
);
as_perror ("Can't read from %s", file_name
);
return_value
= where
+ size
;
as_perror ("Can't close %s", file_name
);