1 /* comm - select lines from two sorted files Author: Martin C. Atkins */
4 * This program was written by:
10 * and is released into the public domain, on the condition
11 * that this comment is always included without alteration.
14 #include <sys/types.h>
19 #include <minix/minlib.h>
22 #define BUFFER_SIZE (512)
26 char *name
; /* the file's name */
27 int fd
; /* the file descripter */
28 char buf
[BUFFER_SIZE
]; /* buffer storage */
29 char *next
; /* the next character to read */
30 char *endp
; /* the first invalid character */
31 int seeneof
; /* an end of file has been seen */
34 char lines
[2][LINMAX
];
36 int colflgs
[3] = {1, 2, 3}; /* number of tabs + 1: 0 => no column */
38 static char *umsg
= "Usage: comm [-[123]] file1 file2\n";
40 _PROTOTYPE(int main
, (int argc
, char **argv
));
41 _PROTOTYPE(void usage
, (void));
42 _PROTOTYPE(void error
, (char *s
, char *f
));
43 _PROTOTYPE(void eopen
, (char *fn
, struct file
*file
));
44 _PROTOTYPE(int getbuf
, (struct file
*file
));
45 _PROTOTYPE(int readline
, (int fno
));
46 _PROTOTYPE(void comm
, (void));
47 _PROTOTYPE(void putcol
, (int col
, char *buf
));
48 _PROTOTYPE(void cpycol
, (int col
));
55 if (argc
> 1 && argv
[1][0] == '-' && argv
[1][1] != '\0') {
57 for (ap
= &argv
[1][1]; *ap
; ap
++) switch (*ap
) {
62 if (colflgs
[cnt
] == 0) break;
64 for (cnt
++; cnt
< 3; cnt
++) colflgs
[cnt
]--;
71 if (argc
!= 3) usage();
72 eopen(argv
[1], &files
[0]);
73 eopen(argv
[2], &files
[1]);
100 file
->next
= file
->endp
= &file
->buf
[0];
102 if (fn
[0] == '-' && fn
[1] == '\0')
104 else if ((file
->fd
= open(fn
, O_RDONLY
)) < 0)
105 error("can't open ", fn
);
112 /* Get a buffer-full from the file. Return true if no characters
113 * were obtained because we are at end of file.
117 if (file
->seeneof
) return(1);
118 if ((n
= read(file
->fd
, &file
->buf
[0], BUFFER_SIZE
)) < 0)
119 error("read error on ", file
->name
);
124 file
->next
= &file
->buf
[0];
125 file
->endp
= &file
->buf
[n
];
133 /* Read up to the next '\n' character to buf.
134 * Return a complete line, even if end of file occurs within a line.
135 * Return false at end of file/
137 register struct file
*file
= &files
[fno
];
138 char *buf
= lines
[fno
];
140 if (file
->next
== file
->endp
&& getbuf(file
)) return(0);
141 while ((*buf
++ = *file
->next
++) != '\n')
142 if (file
->next
== file
->endp
&& getbuf(file
)) {
165 if ((res
= strcmp(lines
[0], lines
[1])) != 0) {
167 putcol(res
, lines
[res
]);
168 if (!readline(res
)) {
169 putcol(!res
, lines
[!res
]);
174 putcol(2, lines
[0]); /* files[1]lin == f2lin */
190 void putcol(col
, buf
)
196 if (colflgs
[col
] == 0) return;
197 for (cnt
= 0; cnt
< colflgs
[col
] - 1; cnt
++) printf("\t");
204 if (colflgs
[col
]) while (readline(col
))
205 putcol(col
, lines
[col
]);