Small comm implementatin from Rob Sullivan. Needed to build perl.

This commit is contained in:
Rob Landley 2005-05-11 23:12:49 +00:00
parent b662f0d58b
commit 2acfd7bd26
5 changed files with 177 additions and 0 deletions

View File

@ -128,6 +128,9 @@ Pavel Roskin <proski@gnu.org>
Gyepi Sam <gyepi@praxis-sw.com> Gyepi Sam <gyepi@praxis-sw.com>
Remote logging feature for syslogd Remote logging feature for syslogd
Rob Sullivan <cogito.ergo.cogito@gmail.com>
comm
Linus Torvalds <torvalds@transmeta.com> Linus Torvalds <torvalds@transmeta.com>
mkswap, fsck.minix, mkfs.minix mkswap, fsck.minix, mkfs.minix

View File

@ -59,6 +59,13 @@ config CONFIG_CMP
cmp is used to compare two files and returns the result cmp is used to compare two files and returns the result
to standard output. to standard output.
config CONFIG_COMM
bool "comm"
default n
help
comm is used to compare two files line by line and return
a three-column output.
config CONFIG_CP config CONFIG_CP
bool "cp" bool "cp"
default n default n

155
coreutils/comm.c Normal file
View File

@ -0,0 +1,155 @@
/* vi: set sw=4 ts=4: */
/*
* Mini comm implementation for busybox
*
* Copyright (C) 2005 by Robert Sullivan <cogito.ergo.cogito@gmail.com>
*
* This program 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 2 of the License, or
* (at your option) any later version.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
* 02111-1307 USA
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "busybox.h"
#define COMM_OPT_1 0x01
#define COMM_OPT_2 0x02
#define COMM_OPT_3 0x04
/* These three variables control behaviour if non-zero */
static int only_file_1;
static int only_file_2;
static int both;
/* writeline outputs the input given, appropriately aligned according to class */
static void writeline (char *line, int class) {
switch (class) {
case 1: if (!only_file_1)
return;
break;
case 2: if (!only_file_2)
return;
if (only_file_1)
putchar('\t');
break;
case 3: if (!both)
return;
if (only_file_1)
putchar('\t');
if (only_file_2)
putchar('\t');
break;
}
fputs(line, stdout);
}
/* This is the real core of the program - lines are compared here */
static int cmp_files(char **infiles) {
char thisline[2][100];
FILE *streams[2];
int i = 0;
for (i = 0; i < 2; i++) {
streams[i] = (strcmp(infiles[i], "=") == 0 ? stdin : fopen(infiles[i], "r"));
fgets(thisline[i], 100, streams[i]);
}
while (thisline[0] || thisline[1]) {
int order = 0;
int tl0_len = strlen(thisline[0]);
int tl1_len = strlen(thisline[1]);
if (!thisline[0])
order = 1;
else if (!thisline[1])
order = -1;
else {
order = memcmp(thisline[0], thisline[1], tl0_len < tl1_len ? tl0_len : tl1_len);
if (!order)
order = tl0_len < tl1_len ? -1 : tl0_len != tl1_len;
}
if ((order == 0) && (!feof(streams[0])) && (!feof(streams[1])))
writeline(thisline[1], 3);
else if ((order > 0) && (!feof(streams[1])))
writeline(thisline[1], 2);
else if ((order < 0) && (!feof(streams[0])))
writeline(thisline[0], 1);
if (feof(streams[0]) && feof(streams[1])) {
fclose(streams[0]);
fclose(streams[1]);
break;
}
else if (feof(streams[0])) {
while (!feof(streams[1])) {
if (order < 0)
writeline(thisline[1], 2);
fgets(thisline[1], 100, streams[1]);
}
fclose(streams[0]);
fclose(streams[1]);
break;
}
else if (feof(streams[1])) {
while (!feof(streams[0])) {
if (order > 0)
writeline(thisline[0], 1);
fgets(thisline[0], 100, streams[0]);
}
fclose(streams[0]);
fclose(streams[1]);
break;
}
else {
if (order >= 0)
fgets(thisline[1], 100, streams[1]);
if (order <= 0)
fgets(thisline[0], 100, streams[0]);
}
}
return 0;
}
int comm_main (int argc, char **argv) {
unsigned long opt;
only_file_1 = 1;
only_file_2 = 1;
both = 1;
opt = bb_getopt_ulflags(argc, argv, "123");
if ((opt & 0x80000000UL) || (optind == argc)) {
bb_show_usage();
}
if (opt & COMM_OPT_1)
only_file_1 = 0;
if (opt & COMM_OPT_2)
only_file_2 = 0;
if (opt & COMM_OPT_3)
both = 0;
exit(cmp_files(argv + optind) == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
}

View File

@ -113,6 +113,9 @@
#ifdef CONFIG_CMP #ifdef CONFIG_CMP
APPLET(cmp, cmp_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER) APPLET(cmp, cmp_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
#endif #endif
#ifdef CONFIG_COMM
APPLET(comm, comm_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
#endif
#ifdef CONFIG_CP #ifdef CONFIG_CP
APPLET(cp, cp_main, _BB_DIR_BIN, _BB_SUID_NEVER) APPLET(cp, cp_main, _BB_DIR_BIN, _BB_SUID_NEVER)
#endif #endif

View File

@ -222,6 +222,15 @@
"\t\t for all differing bytes\n" \ "\t\t for all differing bytes\n" \
"\t-s\tquiet mode - do not print" "\t-s\tquiet mode - do not print"
#define comm_trivial_usage \
"[-123] FILE1 FILE2"
#define comm_full_usage \
"Compare files. Compares FILE1 to FILE2, or to stdin if - is specified.\n\n" \
"Options:\n" \
"\t-1\tSuppress lines unique to FILE1\n" \
"\t-2\tSuppress lines unique to FILE2\n" \
"\t-3\tSuppress lines common to both files"
#define cp_trivial_usage \ #define cp_trivial_usage \
"[OPTION]... SOURCE DEST" "[OPTION]... SOURCE DEST"
#define cp_full_usage \ #define cp_full_usage \