char *stpcpy ();
char *xmalloc ();
void error ();
+int full_write ();
+int safe_read ();
static void cat ();
static void next_line_num ();
{
/* Read a block of input. */
- n_read = read (input_desc, buf, bufsize);
+ n_read = safe_read (input_desc, buf, bufsize);
if (n_read < 0)
{
error (0, errno, "%s", infile);
/* Write this block out. */
- if (write (output_desc, buf, n_read) != n_read)
+ if (full_write (output_desc, buf, n_read) < 0)
error (1, errno, "write error");
}
}
unsigned char *wp = outbuf;
do
{
- if (write (output_desc, wp, outsize) != outsize)
+ if (full_write (output_desc, wp, outsize) < 0)
error (1, errno, "write error");
wp += outsize;
}
{
int n_write = bpout - outbuf;
- if (write (output_desc, outbuf, n_write) != n_write)
+ if (full_write (output_desc, outbuf, n_write) < 0)
error (1, errno, "write error");
bpout = outbuf;
}
/* Read more input into INBUF. */
- n_read = read (input_desc, inbuf, insize);
+ n_read = safe_read (input_desc, inbuf, insize);
if (n_read < 0)
{
error (0, errno, "%s", infile);
#endif /* INT_MAX */
void error ();
+int safe_read ();
static char *xrealloc ();
if (max == 0)
return 0;
- bytes_read = read (input_desc, dest, max);
+ bytes_read = safe_read (input_desc, dest, max);
if (bytes_read == 0)
have_read_eof = TRUE;
};
void error ();
-void xwrite ();
+int safe_read ();
static int head ();
static int head_bytes ();
if (have_read_stdin && close (0) < 0)
error (1, errno, "-");
- if (close (1) < 0)
+ if (fclose (stdout) == EOF)
error (1, errno, "write error");
exit (exit_status);
{
static int first_file = 1;
- if (first_file)
- {
- xwrite (1, "==> ", 4);
- first_file = 0;
- }
- else
- xwrite (1, "\n==> ", 5);
- xwrite (1, filename, strlen (filename));
- xwrite (1, " <==\n", 5);
+ printf ("%s==> %s <==\n", (first_file ? "" : "\n"), filename);
+ first_file = 0;
}
static int
while (bytes_to_write)
{
- bytes_read = read (fd, buffer, BUFSIZE);
- if (bytes_read == -1)
+ bytes_read = safe_read (fd, buffer, BUFSIZE);
+ if (bytes_read < 0)
{
error (0, errno, "%s", filename);
return 1;
break;
if (bytes_read > bytes_to_write)
bytes_read = bytes_to_write;
- xwrite (1, buffer, bytes_read);
+ if (fwrite (buffer, 1, bytes_read, stdout) == 0)
+ error (1, errno, "write error");
bytes_to_write -= bytes_read;
}
return 0;
while (lines_to_write)
{
- bytes_read = read (fd, buffer, BUFSIZE);
- if (bytes_read == -1)
+ bytes_read = safe_read (fd, buffer, BUFSIZE);
+ if (bytes_read < 0)
{
error (0, errno, "%s", filename);
return 1;
while (bytes_to_write < bytes_read)
if (buffer[bytes_to_write++] == '\n' && --lines_to_write == 0)
break;
- xwrite (1, buffer, bytes_to_write);
+ if (fwrite (buffer, 1, bytes_to_write, stdout) == 0)
+ error (1, errno, "write error");
}
return 0;
}
static void usage ();
#define min(A, B) ((A) < (B) ? (A) : (B))
+#define max(A, B) ((A) > (B) ? (A) : (B))
/* An element of the list describing the format of each
output line. */
{NULL, 0, NULL, 0}
};
+/* Used to print non-joining lines */
+static struct line blank1;
+static struct line blank2;
+
/* Fill in the `fields' structure in LINE. */
static void
if (diff < 0)
{
if (print_unpairables_1)
- prline (&seq1.lines[0]);
+ prjoin (&seq1.lines[0], &blank2);
freeline (&seq1.lines[0]);
seq1.count = 0;
getseq (fp1, &seq1);
if (diff > 0)
{
if (print_unpairables_2)
- prline (&seq2.lines[0]);
+ prjoin (&blank1, &seq2.lines[0]);
freeline (&seq2.lines[0]);
seq2.count = 0;
getseq (fp2, &seq2);
if (print_unpairables_1 && seq1.count)
{
- prline (&seq1.lines[0]);
+ prjoin(&seq1.lines[0], &blank2);
freeline (&seq1.lines[0]);
while (get_line (fp1, &line))
{
- prline (&line);
+ prjoin(&line, &blank2);
freeline (&line);
}
}
if (print_unpairables_2 && seq2.count)
{
- prline (&seq2.lines[0]);
+ prjoin(&blank1, &seq2.lines[0]);
freeline (&seq2.lines[0]);
while (get_line (fp2, &line))
{
- prline (&line);
+ prjoin(&blank1, &line);
freeline (&line);
}
}
if (*str == ',' || ISBLANK (*str))
{
added += add_field (file, field);
+ switch (file) {
+ case 1: blank1.nfields = max(blank1.nfields, field); break;
+ case 2: blank2.nfields = max(blank2.nfields, field); break;
+ }
file = field = -1;
dot_found = 0;
}
return added;
}
+/* Create a blank line with COUNT fields separated by tabs. */
+
+void
+make_blank (blank, count)
+ struct line *blank;
+ int count;
+{
+ int i;
+ blank->beg = xmalloc(blank->nfields + 1);
+ blank->fields = (struct field *)xmalloc(sizeof(struct field) * count);
+ for (i = 0; i < blank->nfields; i++) {
+ blank->beg[i] = '\t';
+ blank->fields[i].lim = blank->fields[i].beg = &blank->beg[i];
+ }
+ blank->beg[i] = '\0';
+ blank->lim = &blank->beg[i];
+}
+
void
main (argc, argv)
int argc;
FILE *fp1, *fp2;
int optc, prev_optc = 0, nfiles, val;
+ blank1.nfields = 1;
+ blank2.nfields = 1;
+
program_name = argv[0];
parse_long_options (argc, argv, usage);
+ /* Now that we've seen the options, we can construct the blank line
+ structures. */
+ make_blank(&blank1, blank1.nfields);
+ make_blank(&blank2, blank2.nfields);
+
nfiles = 0;
print_pairables = 1;
char *xmalloc ();
void error ();
+int full_write ();
+int safe_read ();
static int convint ();
static int isdigits ();
if (output_desc < 0)
error (1, errno, "%s", outfile);
}
- if (write (output_desc, bp, bytes) < 0)
+ if (full_write (output_desc, bp, bytes) < 0)
error (1, errno, "%s", outfile);
}
while (to_be_read)
{
- n_read = read (input_desc, buf, to_be_read);
+ n_read = safe_read (input_desc, buf, to_be_read);
if (n_read < 0)
return -1;
if (n_read == 0)
static int sysv_sum_file ();
void error ();
+int safe_read ();
/* The name this program was run with. */
char *program_name;
}
}
- while ((bytes_read = read (fd, buf, sizeof buf)) > 0)
+ while ((bytes_read = safe_read (fd, buf, sizeof buf)) > 0)
{
register int i;
static void xwrite ();
void error ();
+int full_write ();
+int safe_read ();
/* The name this program was run with. */
char *program_name;
error (0, errno, "%s", tempfile);
cleanup ();
}
- while ((bytes_read = read (0, buffer, read_size)) > 0)
- if (write (fd, buffer, bytes_read) != bytes_read)
+ while ((bytes_read = safe_read (0, buffer, read_size)) > 0)
+ if (full_write (fd, buffer, bytes_read) < 0)
{
error (0, errno, "%s", tempfile);
cleanup ();
in the input file. */
lseek (fd, file_pos, SEEK_SET);
- if (read (fd, buffer, saved_record_size) != saved_record_size)
+ if (safe_read (fd, buffer, saved_record_size) != saved_record_size)
{
error (0, 1, "%s", file);
return 1;
else
match_start = past_end;
- if (read (fd, buffer, read_size) != read_size)
+ if (safe_read (fd, buffer, read_size) != read_size)
{
error (0, errno, "%s", file);
return 1;
char *buffer;
int size;
{
- if (write (desc, buffer, size) != size)
+ if (full_write (desc, buffer, size) < 0)
{
error (0, errno, "write error");
cleanup ();
#endif
#include <stdio.h>
+#include <assert.h>
#include <getopt.h>
#include <sys/types.h>
#include "system.h"
#include "version.h"
+/* FIXME: uncomment before release. */
+/* #define NDEBUG 1 */
+
+#define XWRITE(fd, buffer, n_bytes) \
+ do \
+ { \
+ assert ((fd) == 1); \
+ assert ((n_bytes) > 0); \
+ if (fwrite ((buffer), 1, (n_bytes), stdout) == 0) \
+ error (1, errno, "write error"); \
+ } \
+ while (0)
+
/* Number of items to tail. */
#define DEFAULT_NUMBER 10
+/* FIXME: use definition from stdio.h. */
/* Size of atomic reads. */
#define BUFSIZE (512 * 8)
};
char *xmalloc ();
-void xwrite ();
void error ();
+int safe_read ();
static int file_lines ();
static int pipe_bytes ();
if (have_read_stdin && close (0) < 0)
error (1, errno, "-");
- if (close (1) < 0)
+ if (fclose (stdout) == EOF)
error (1, errno, "write error");
exit (exit_status);
}
{
static int first_file = 1;
- if (first_file)
- {
- xwrite (1, "==> ", 4);
- first_file = 0;
- }
- else
- xwrite (1, "\n==> ", 5);
- xwrite (1, filename, strlen (filename));
- xwrite (1, " <==\n", 5);
+ printf ("%s==> %s <==\n", (first_file ? "" : "\n"), filename);
+ first_file = 0;
}
/* Display the last NUMBER units of file FILENAME, open for reading
reads will be on block boundaries, which might increase efficiency. */
pos -= bytes_read;
lseek (fd, pos, SEEK_SET);
- bytes_read = read (fd, buffer, bytes_read);
+ bytes_read = safe_read (fd, buffer, bytes_read);
if (bytes_read == -1)
{
error (0, errno, "%s", filename);
/* If this newline wasn't the last character in the buffer,
print the text after it. */
if (i != bytes_read - 1)
- xwrite (1, &buffer[i + 1], bytes_read - (i + 1));
+ XWRITE (1, &buffer[i + 1], bytes_read - (i + 1));
return 0;
}
}
pos -= BUFSIZE;
lseek (fd, pos, SEEK_SET);
}
- while ((bytes_read = read (fd, buffer, BUFSIZE)) > 0);
+ while ((bytes_read = safe_read (fd, buffer, BUFSIZE)) > 0);
if (bytes_read == -1)
{
error (0, errno, "%s", filename);
tmp = (LBUFFER *) xmalloc (sizeof (LBUFFER));
/* Input is always read into a fresh buffer. */
- while ((tmp->nbytes = read (fd, tmp->buffer, BUFSIZE)) > 0)
+ while ((tmp->nbytes = safe_read (fd, tmp->buffer, BUFSIZE)) > 0)
{
tmp->nlines = 0;
tmp->next = NULL;
}
else
i = 0;
- xwrite (1, &tmp->buffer[i], tmp->nbytes - i);
+ XWRITE (1, &tmp->buffer[i], tmp->nbytes - i);
for (tmp = tmp->next; tmp; tmp = tmp->next)
- xwrite (1, tmp->buffer, tmp->nbytes);
+ XWRITE (1, tmp->buffer, tmp->nbytes);
free_lbuffers:
while (first)
tmp = (CBUFFER *) xmalloc (sizeof (CBUFFER));
/* Input is always read into a fresh buffer. */
- while ((tmp->nbytes = read (fd, tmp->buffer, BUFSIZE)) > 0)
+ while ((tmp->nbytes = safe_read (fd, tmp->buffer, BUFSIZE)) > 0)
{
tmp->next = NULL;
i = total_bytes - number;
else
i = 0;
- xwrite (1, &tmp->buffer[i], tmp->nbytes - i);
+ XWRITE (1, &tmp->buffer[i], tmp->nbytes - i);
for (tmp = tmp->next; tmp; tmp = tmp->next)
- xwrite (1, tmp->buffer, tmp->nbytes);
+ XWRITE (1, tmp->buffer, tmp->nbytes);
free_cbuffers:
while (first)
char buffer[BUFSIZE];
int bytes_read = 0;
- while (number > 0 && (bytes_read = read (fd, buffer, BUFSIZE)) > 0)
+ while (number > 0 && (bytes_read = safe_read (fd, buffer, BUFSIZE)) > 0)
number -= bytes_read;
if (bytes_read == -1)
{
return 1;
}
else if (number < 0)
- xwrite (1, &buffer[bytes_read + number], -number);
+ XWRITE (1, &buffer[bytes_read + number], -number);
return 0;
}
int bytes_read = 0;
int bytes_to_skip = 0;
- while (number && (bytes_read = read (fd, buffer, BUFSIZE)) > 0)
+ while (number && (bytes_read = safe_read (fd, buffer, BUFSIZE)) > 0)
{
bytes_to_skip = 0;
while (bytes_to_skip < bytes_read)
return 1;
}
else if (bytes_to_skip < bytes_read)
- xwrite (1, &buffer[bytes_to_skip], bytes_read - bytes_to_skip);
+ XWRITE (1, &buffer[bytes_to_skip], bytes_read - bytes_to_skip);
return 0;
}
total = 0;
output:
- while ((bytes_read = read (fd, buffer, BUFSIZE)) > 0)
+ while ((bytes_read = safe_read (fd, buffer, BUFSIZE)) > 0)
{
- xwrite (1, buffer, bytes_read);
+ XWRITE (1, buffer, bytes_read);
total += bytes_read;
}
if (bytes_read == -1)
char *xmalloc ();
char *stpcpy ();
void error ();
+int safe_read ();
/* The name by which this program was run. */
char *program_name;
if (i >= nr)
{
if (reader == NULL)
- nr = read (0, (char *) buf, size);
+ nr = safe_read (0, (char *) buf, size);
else
nr = (*reader) (buf, size, NULL);
do
{
int i;
- int nr = read (0, (char *) buf, size);
+ int nr = safe_read (0, (char *) buf, size);
if (nr < 0)
error (1, errno, "read error");
if (hit_eof)
return 0;
- chars_read = read (0, (char *) buf, size);
+ chars_read = safe_read (0, (char *) buf, size);
if (chars_read < 0)
error (1, errno, "read error");
if (chars_read == 0)
#define BUFFER_SIZE (16 * 1024)
void error ();
+int safe_read ();
static void wc ();
static void wc_file ();
}
else
{
- while ((bytes_read = read (fd, buf, BUFFER_SIZE)) > 0)
+ while ((bytes_read = safe_read (fd, buf, BUFFER_SIZE)) > 0)
{
register char *p = buf;