mirror of
git://git.sv.gnu.org/coreutils
synced 2026-06-04 06:45:12 -04:00
Protoize. Reorder functions to obviate forward dcls.
Remove forward dcls.
This commit is contained in:
@@ -14,7 +14,7 @@
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
|
||||
/* Differences from the Unix cat:
|
||||
* Always unbuffered, -u is ignored.
|
||||
* Usually much faster than other versions of cat, the difference
|
||||
@@ -43,10 +43,6 @@ char *xmalloc ();
|
||||
int full_write ();
|
||||
int safe_read ();
|
||||
|
||||
static void cat ();
|
||||
static void next_line_num ();
|
||||
static void simple_cat ();
|
||||
|
||||
/* Name under which this program was invoked. */
|
||||
char *program_name;
|
||||
|
||||
@@ -114,7 +110,336 @@ With no FILE, or when FILE is -, read standard input.\n\
|
||||
exit (status);
|
||||
}
|
||||
|
||||
|
||||
/* Compute the next line number. */
|
||||
|
||||
static void
|
||||
next_line_num ()
|
||||
{
|
||||
char *endp = line_num_end;
|
||||
do
|
||||
{
|
||||
if ((*endp)++ < '9')
|
||||
return;
|
||||
*endp-- = '0';
|
||||
}
|
||||
while (endp >= line_num_start);
|
||||
*--line_num_start = '1';
|
||||
if (line_num_start < line_num_print)
|
||||
line_num_print--;
|
||||
}
|
||||
|
||||
/* Plain cat. Copies the file behind `input_desc' to the file behind
|
||||
`output_desc'. */
|
||||
|
||||
static void
|
||||
simple_cat (
|
||||
/* Pointer to the buffer, used by reads and writes. */
|
||||
unsigned char *buf,
|
||||
|
||||
/* Number of characters preferably read or written by each read and write
|
||||
call. */
|
||||
int bufsize)
|
||||
{
|
||||
/* Actual number of characters read, and therefore written. */
|
||||
int n_read;
|
||||
|
||||
/* Loop until the end of the file. */
|
||||
|
||||
for (;;)
|
||||
{
|
||||
/* Read a block of input. */
|
||||
|
||||
n_read = safe_read (input_desc, buf, bufsize);
|
||||
if (n_read < 0)
|
||||
{
|
||||
error (0, errno, "%s", infile);
|
||||
exit_stat = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
/* End of this file? */
|
||||
|
||||
if (n_read == 0)
|
||||
break;
|
||||
|
||||
/* Write this block out. */
|
||||
|
||||
if (full_write (output_desc, buf, n_read) < 0)
|
||||
error (1, errno, _("write error"));
|
||||
}
|
||||
}
|
||||
|
||||
/* Cat the file behind INPUT_DESC to the file behind OUTPUT_DESC.
|
||||
Called if any option more than -u was specified.
|
||||
|
||||
A newline character is always put at the end of the buffer, to make
|
||||
an explicit test for buffer end unnecessary. */
|
||||
|
||||
static void
|
||||
cat (
|
||||
/* Pointer to the beginning of the input buffer. */
|
||||
unsigned char *inbuf,
|
||||
|
||||
/* Number of characters read in each read call. */
|
||||
int insize,
|
||||
|
||||
/* Pointer to the beginning of the output buffer. */
|
||||
unsigned char *outbuf,
|
||||
|
||||
/* Number of characters written by each write call. */
|
||||
int outsize,
|
||||
|
||||
/* Variables that have values according to the specified options. */
|
||||
int quote,
|
||||
int output_tabs,
|
||||
int numbers,
|
||||
int numbers_at_empty_lines,
|
||||
int mark_line_ends,
|
||||
int squeeze_empty_lines)
|
||||
{
|
||||
/* Last character read from the input buffer. */
|
||||
unsigned char ch;
|
||||
|
||||
/* Pointer to the next character in the input buffer. */
|
||||
unsigned char *bpin;
|
||||
|
||||
/* Pointer to the first non-valid byte in the input buffer, i.e. the
|
||||
current end of the buffer. */
|
||||
unsigned char *eob;
|
||||
|
||||
/* Pointer to the position where the next character shall be written. */
|
||||
unsigned char *bpout;
|
||||
|
||||
/* Number of characters read by the last read call. */
|
||||
int n_read;
|
||||
|
||||
/* Determines how many consecutive newlines there have been in the
|
||||
input. 0 newlines makes NEWLINES -1, 1 newline makes NEWLINES 1,
|
||||
etc. Initially 0 to indicate that we are at the beginning of a
|
||||
new line. The "state" of the procedure is determined by
|
||||
NEWLINES. */
|
||||
int newlines = newlines2;
|
||||
|
||||
#ifdef FIONREAD
|
||||
/* If nonzero, use the FIONREAD ioctl, as an optimization.
|
||||
(On Ultrix, it is not supported on NFS filesystems.) */
|
||||
int use_fionread = 1;
|
||||
#endif
|
||||
|
||||
/* The inbuf pointers are initialized so that BPIN > EOB, and thereby input
|
||||
is read immediately. */
|
||||
|
||||
eob = inbuf;
|
||||
bpin = eob + 1;
|
||||
|
||||
bpout = outbuf;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
do
|
||||
{
|
||||
/* Write if there are at least OUTSIZE bytes in OUTBUF. */
|
||||
|
||||
if (bpout - outbuf >= outsize)
|
||||
{
|
||||
unsigned char *wp = outbuf;
|
||||
do
|
||||
{
|
||||
if (full_write (output_desc, wp, outsize) < 0)
|
||||
error (1, errno, _("write error"));
|
||||
wp += outsize;
|
||||
}
|
||||
while (bpout - wp >= outsize);
|
||||
|
||||
/* Move the remaining bytes to the beginning of the
|
||||
buffer. */
|
||||
|
||||
memmove (outbuf, wp, bpout - wp);
|
||||
bpout = outbuf + (bpout - wp);
|
||||
}
|
||||
|
||||
/* Is INBUF empty? */
|
||||
|
||||
if (bpin > eob)
|
||||
{
|
||||
#ifdef FIONREAD
|
||||
int n_to_read = 0;
|
||||
|
||||
/* Is there any input to read immediately?
|
||||
If not, we are about to wait,
|
||||
so write all buffered output before waiting. */
|
||||
|
||||
if (use_fionread
|
||||
&& ioctl (input_desc, FIONREAD, &n_to_read) < 0)
|
||||
{
|
||||
/* Ultrix returns EOPNOTSUPP on NFS;
|
||||
HP-UX returns ENOTTY on pipes.
|
||||
SunOS returns EINVAL and
|
||||
More/BSD returns ENODEV on special files
|
||||
like /dev/null.
|
||||
Irix-5 returns ENOSYS on pipes. */
|
||||
if (errno == EOPNOTSUPP || errno == ENOTTY
|
||||
|| errno == EINVAL || errno == ENODEV
|
||||
#ifdef ENOSYS
|
||||
|| errno == ENOSYS
|
||||
#endif
|
||||
)
|
||||
use_fionread = 0;
|
||||
else
|
||||
{
|
||||
error (0, errno, _("cannot do ioctl on `%s'"), infile);
|
||||
exit_stat = 1;
|
||||
newlines2 = newlines;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (n_to_read == 0)
|
||||
#endif
|
||||
{
|
||||
int n_write = bpout - outbuf;
|
||||
|
||||
if (full_write (output_desc, outbuf, n_write) < 0)
|
||||
error (1, errno, _("write error"));
|
||||
bpout = outbuf;
|
||||
}
|
||||
|
||||
/* Read more input into INBUF. */
|
||||
|
||||
n_read = safe_read (input_desc, inbuf, insize);
|
||||
if (n_read < 0)
|
||||
{
|
||||
error (0, errno, "%s", infile);
|
||||
exit_stat = 1;
|
||||
newlines2 = newlines;
|
||||
return;
|
||||
}
|
||||
if (n_read == 0)
|
||||
{
|
||||
newlines2 = newlines;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Update the pointers and insert a sentinel at the buffer
|
||||
end. */
|
||||
|
||||
bpin = inbuf;
|
||||
eob = bpin + n_read;
|
||||
*eob = '\n';
|
||||
}
|
||||
else
|
||||
{
|
||||
/* It was a real (not a sentinel) newline. */
|
||||
|
||||
/* Was the last line empty?
|
||||
(i.e. have two or more consecutive newlines been read?) */
|
||||
|
||||
if (++newlines > 0)
|
||||
{
|
||||
/* Are multiple adjacent empty lines to be substituted by
|
||||
single ditto (-s), and this was the second empty line? */
|
||||
|
||||
if (squeeze_empty_lines && newlines >= 2)
|
||||
{
|
||||
ch = *bpin++;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Are line numbers to be written at empty lines (-n)? */
|
||||
|
||||
if (numbers && numbers_at_empty_lines)
|
||||
{
|
||||
next_line_num ();
|
||||
bpout = (unsigned char *) stpcpy (bpout, line_num_print);
|
||||
}
|
||||
}
|
||||
|
||||
/* Output a currency symbol if requested (-e). */
|
||||
|
||||
if (mark_line_ends)
|
||||
*bpout++ = '$';
|
||||
|
||||
/* Output the newline. */
|
||||
|
||||
*bpout++ = '\n';
|
||||
}
|
||||
ch = *bpin++;
|
||||
}
|
||||
while (ch == '\n');
|
||||
|
||||
/* Are we at the beginning of a line, and line numbers are requested? */
|
||||
|
||||
if (newlines >= 0 && numbers)
|
||||
{
|
||||
next_line_num ();
|
||||
bpout = (unsigned char *) stpcpy (bpout, line_num_print);
|
||||
}
|
||||
|
||||
/* Here CH cannot contain a newline character. */
|
||||
|
||||
/* The loops below continue until a newline character is found,
|
||||
which means that the buffer is empty or that a proper newline
|
||||
has been found. */
|
||||
|
||||
/* If quoting, i.e. at least one of -v, -e, or -t specified,
|
||||
scan for chars that need conversion. */
|
||||
if (quote)
|
||||
for (;;)
|
||||
{
|
||||
if (ch >= 32)
|
||||
{
|
||||
if (ch < 127)
|
||||
*bpout++ = ch;
|
||||
else if (ch == 127)
|
||||
*bpout++ = '^',
|
||||
*bpout++ = '?';
|
||||
else
|
||||
{
|
||||
*bpout++ = 'M',
|
||||
*bpout++ = '-';
|
||||
if (ch >= 128 + 32)
|
||||
if (ch < 128 + 127)
|
||||
*bpout++ = ch - 128;
|
||||
else
|
||||
*bpout++ = '^',
|
||||
*bpout++ = '?';
|
||||
else
|
||||
*bpout++ = '^',
|
||||
*bpout++ = ch - 128 + 64;
|
||||
}
|
||||
}
|
||||
else if (ch == '\t' && output_tabs)
|
||||
*bpout++ = '\t';
|
||||
else if (ch == '\n')
|
||||
{
|
||||
newlines = -1;
|
||||
break;
|
||||
}
|
||||
else
|
||||
*bpout++ = '^',
|
||||
*bpout++ = ch + 64;
|
||||
|
||||
ch = *bpin++;
|
||||
}
|
||||
else
|
||||
/* Not quoting, neither of -v, -e, or -t specified. */
|
||||
for (;;)
|
||||
{
|
||||
if (ch == '\t' && !output_tabs)
|
||||
*bpout++ = '^',
|
||||
*bpout++ = ch + 64;
|
||||
else if (ch != '\n')
|
||||
*bpout++ = ch;
|
||||
else
|
||||
{
|
||||
newlines = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
ch = *bpin++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
main (argc, argv)
|
||||
int argc;
|
||||
@@ -397,336 +722,3 @@ main (argc, argv)
|
||||
|
||||
exit (exit_stat);
|
||||
}
|
||||
|
||||
/* Plain cat. Copies the file behind `input_desc' to the file behind
|
||||
`output_desc'. */
|
||||
|
||||
static void
|
||||
simple_cat (buf, bufsize)
|
||||
/* Pointer to the buffer, used by reads and writes. */
|
||||
unsigned char *buf;
|
||||
|
||||
/* Number of characters preferably read or written by each read and write
|
||||
call. */
|
||||
int bufsize;
|
||||
{
|
||||
/* Actual number of characters read, and therefore written. */
|
||||
int n_read;
|
||||
|
||||
/* Loop until the end of the file. */
|
||||
|
||||
for (;;)
|
||||
{
|
||||
/* Read a block of input. */
|
||||
|
||||
n_read = safe_read (input_desc, buf, bufsize);
|
||||
if (n_read < 0)
|
||||
{
|
||||
error (0, errno, "%s", infile);
|
||||
exit_stat = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
/* End of this file? */
|
||||
|
||||
if (n_read == 0)
|
||||
break;
|
||||
|
||||
/* Write this block out. */
|
||||
|
||||
if (full_write (output_desc, buf, n_read) < 0)
|
||||
error (1, errno, _("write error"));
|
||||
}
|
||||
}
|
||||
|
||||
/* Cat the file behind INPUT_DESC to the file behind OUTPUT_DESC.
|
||||
Called if any option more than -u was specified.
|
||||
|
||||
A newline character is always put at the end of the buffer, to make
|
||||
an explicit test for buffer end unnecessary. */
|
||||
|
||||
static void
|
||||
cat (inbuf, insize, outbuf, outsize, quote,
|
||||
output_tabs, numbers, numbers_at_empty_lines,
|
||||
mark_line_ends, squeeze_empty_lines)
|
||||
|
||||
/* Pointer to the beginning of the input buffer. */
|
||||
unsigned char *inbuf;
|
||||
|
||||
/* Number of characters read in each read call. */
|
||||
int insize;
|
||||
|
||||
/* Pointer to the beginning of the output buffer. */
|
||||
unsigned char *outbuf;
|
||||
|
||||
/* Number of characters written by each write call. */
|
||||
int outsize;
|
||||
|
||||
/* Variables that have values according to the specified options. */
|
||||
int quote;
|
||||
int output_tabs;
|
||||
int numbers;
|
||||
int numbers_at_empty_lines;
|
||||
int mark_line_ends;
|
||||
int squeeze_empty_lines;
|
||||
{
|
||||
/* Last character read from the input buffer. */
|
||||
unsigned char ch;
|
||||
|
||||
/* Pointer to the next character in the input buffer. */
|
||||
unsigned char *bpin;
|
||||
|
||||
/* Pointer to the first non-valid byte in the input buffer, i.e. the
|
||||
current end of the buffer. */
|
||||
unsigned char *eob;
|
||||
|
||||
/* Pointer to the position where the next character shall be written. */
|
||||
unsigned char *bpout;
|
||||
|
||||
/* Number of characters read by the last read call. */
|
||||
int n_read;
|
||||
|
||||
/* Determines how many consecutive newlines there have been in the
|
||||
input. 0 newlines makes NEWLINES -1, 1 newline makes NEWLINES 1,
|
||||
etc. Initially 0 to indicate that we are at the beginning of a
|
||||
new line. The "state" of the procedure is determined by
|
||||
NEWLINES. */
|
||||
int newlines = newlines2;
|
||||
|
||||
#ifdef FIONREAD
|
||||
/* If nonzero, use the FIONREAD ioctl, as an optimization.
|
||||
(On Ultrix, it is not supported on NFS filesystems.) */
|
||||
int use_fionread = 1;
|
||||
#endif
|
||||
|
||||
/* The inbuf pointers are initialized so that BPIN > EOB, and thereby input
|
||||
is read immediately. */
|
||||
|
||||
eob = inbuf;
|
||||
bpin = eob + 1;
|
||||
|
||||
bpout = outbuf;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
do
|
||||
{
|
||||
/* Write if there are at least OUTSIZE bytes in OUTBUF. */
|
||||
|
||||
if (bpout - outbuf >= outsize)
|
||||
{
|
||||
unsigned char *wp = outbuf;
|
||||
do
|
||||
{
|
||||
if (full_write (output_desc, wp, outsize) < 0)
|
||||
error (1, errno, _("write error"));
|
||||
wp += outsize;
|
||||
}
|
||||
while (bpout - wp >= outsize);
|
||||
|
||||
/* Move the remaining bytes to the beginning of the
|
||||
buffer. */
|
||||
|
||||
memmove (outbuf, wp, bpout - wp);
|
||||
bpout = outbuf + (bpout - wp);
|
||||
}
|
||||
|
||||
/* Is INBUF empty? */
|
||||
|
||||
if (bpin > eob)
|
||||
{
|
||||
#ifdef FIONREAD
|
||||
int n_to_read = 0;
|
||||
|
||||
/* Is there any input to read immediately?
|
||||
If not, we are about to wait,
|
||||
so write all buffered output before waiting. */
|
||||
|
||||
if (use_fionread
|
||||
&& ioctl (input_desc, FIONREAD, &n_to_read) < 0)
|
||||
{
|
||||
/* Ultrix returns EOPNOTSUPP on NFS;
|
||||
HP-UX returns ENOTTY on pipes.
|
||||
SunOS returns EINVAL and
|
||||
More/BSD returns ENODEV on special files
|
||||
like /dev/null.
|
||||
Irix-5 returns ENOSYS on pipes. */
|
||||
if (errno == EOPNOTSUPP || errno == ENOTTY
|
||||
|| errno == EINVAL || errno == ENODEV
|
||||
#ifdef ENOSYS
|
||||
|| errno == ENOSYS
|
||||
#endif
|
||||
)
|
||||
use_fionread = 0;
|
||||
else
|
||||
{
|
||||
error (0, errno, _("cannot do ioctl on `%s'"), infile);
|
||||
exit_stat = 1;
|
||||
newlines2 = newlines;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (n_to_read == 0)
|
||||
#endif
|
||||
{
|
||||
int n_write = bpout - outbuf;
|
||||
|
||||
if (full_write (output_desc, outbuf, n_write) < 0)
|
||||
error (1, errno, _("write error"));
|
||||
bpout = outbuf;
|
||||
}
|
||||
|
||||
/* Read more input into INBUF. */
|
||||
|
||||
n_read = safe_read (input_desc, inbuf, insize);
|
||||
if (n_read < 0)
|
||||
{
|
||||
error (0, errno, "%s", infile);
|
||||
exit_stat = 1;
|
||||
newlines2 = newlines;
|
||||
return;
|
||||
}
|
||||
if (n_read == 0)
|
||||
{
|
||||
newlines2 = newlines;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Update the pointers and insert a sentinel at the buffer
|
||||
end. */
|
||||
|
||||
bpin = inbuf;
|
||||
eob = bpin + n_read;
|
||||
*eob = '\n';
|
||||
}
|
||||
else
|
||||
{
|
||||
/* It was a real (not a sentinel) newline. */
|
||||
|
||||
/* Was the last line empty?
|
||||
(i.e. have two or more consecutive newlines been read?) */
|
||||
|
||||
if (++newlines > 0)
|
||||
{
|
||||
/* Are multiple adjacent empty lines to be substituted by
|
||||
single ditto (-s), and this was the second empty line? */
|
||||
|
||||
if (squeeze_empty_lines && newlines >= 2)
|
||||
{
|
||||
ch = *bpin++;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Are line numbers to be written at empty lines (-n)? */
|
||||
|
||||
if (numbers && numbers_at_empty_lines)
|
||||
{
|
||||
next_line_num ();
|
||||
bpout = (unsigned char *) stpcpy (bpout, line_num_print);
|
||||
}
|
||||
}
|
||||
|
||||
/* Output a currency symbol if requested (-e). */
|
||||
|
||||
if (mark_line_ends)
|
||||
*bpout++ = '$';
|
||||
|
||||
/* Output the newline. */
|
||||
|
||||
*bpout++ = '\n';
|
||||
}
|
||||
ch = *bpin++;
|
||||
}
|
||||
while (ch == '\n');
|
||||
|
||||
/* Are we at the beginning of a line, and line numbers are requested? */
|
||||
|
||||
if (newlines >= 0 && numbers)
|
||||
{
|
||||
next_line_num ();
|
||||
bpout = (unsigned char *) stpcpy (bpout, line_num_print);
|
||||
}
|
||||
|
||||
/* Here CH cannot contain a newline character. */
|
||||
|
||||
/* The loops below continue until a newline character is found,
|
||||
which means that the buffer is empty or that a proper newline
|
||||
has been found. */
|
||||
|
||||
/* If quoting, i.e. at least one of -v, -e, or -t specified,
|
||||
scan for chars that need conversion. */
|
||||
if (quote)
|
||||
for (;;)
|
||||
{
|
||||
if (ch >= 32)
|
||||
{
|
||||
if (ch < 127)
|
||||
*bpout++ = ch;
|
||||
else if (ch == 127)
|
||||
*bpout++ = '^',
|
||||
*bpout++ = '?';
|
||||
else
|
||||
{
|
||||
*bpout++ = 'M',
|
||||
*bpout++ = '-';
|
||||
if (ch >= 128 + 32)
|
||||
if (ch < 128 + 127)
|
||||
*bpout++ = ch - 128;
|
||||
else
|
||||
*bpout++ = '^',
|
||||
*bpout++ = '?';
|
||||
else
|
||||
*bpout++ = '^',
|
||||
*bpout++ = ch - 128 + 64;
|
||||
}
|
||||
}
|
||||
else if (ch == '\t' && output_tabs)
|
||||
*bpout++ = '\t';
|
||||
else if (ch == '\n')
|
||||
{
|
||||
newlines = -1;
|
||||
break;
|
||||
}
|
||||
else
|
||||
*bpout++ = '^',
|
||||
*bpout++ = ch + 64;
|
||||
|
||||
ch = *bpin++;
|
||||
}
|
||||
else
|
||||
/* Not quoting, neither of -v, -e, or -t specified. */
|
||||
for (;;)
|
||||
{
|
||||
if (ch == '\t' && !output_tabs)
|
||||
*bpout++ = '^',
|
||||
*bpout++ = ch + 64;
|
||||
else if (ch != '\n')
|
||||
*bpout++ = ch;
|
||||
else
|
||||
{
|
||||
newlines = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
ch = *bpin++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Compute the next line number. */
|
||||
|
||||
static void
|
||||
next_line_num ()
|
||||
{
|
||||
char *endp = line_num_end;
|
||||
do
|
||||
{
|
||||
if ((*endp)++ < '9')
|
||||
return;
|
||||
*endp-- = '0';
|
||||
}
|
||||
while (endp >= line_num_start);
|
||||
*--line_num_start = '1';
|
||||
if (line_num_start < line_num_print)
|
||||
line_num_print--;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user