svn commit: trunk/busybox: coreutils libbb

vda at busybox.net vda at busybox.net
Sat Dec 16 22:18:45 UTC 2006


Author: vda
Date: 2006-12-16 14:18:44 -0800 (Sat, 16 Dec 2006)
New Revision: 16974

Log:
diff: fix -q exit code
last_char_is: sacrifice 9 bytes but avoid double-scan


Modified:
   trunk/busybox/coreutils/diff.c
   trunk/busybox/libbb/last_char_is.c


Changeset:
Modified: trunk/busybox/coreutils/diff.c
===================================================================
--- trunk/busybox/coreutils/diff.c	2006-12-16 19:18:08 UTC (rev 16973)
+++ trunk/busybox/coreutils/diff.c	2006-12-16 22:18:44 UTC (rev 16974)
@@ -50,8 +50,6 @@
 #define D_SKIPPED2	(1<<8)
 
 /* Command line options */
-static unsigned long cmd_flags;
-
 #define FLAG_a	(1<<0)
 #define FLAG_b	(1<<1)
 #define FLAG_d  (1<<2)
@@ -68,12 +66,12 @@
 #define	FLAG_w	(1<<13)
 
 /* XXX: FIXME: the following variables should be static, but gcc currently
- * creates a much bigger object if we do this.  */
+ * creates a much bigger object if we do this. [which version of gcc? --vda] */
 int context, status;
 char *start, *label[2];
 struct stat stb1, stb2;
 char **dl;
-static int dl_count = 0;
+static int dl_count;
 
 struct cand {
 	int x;
@@ -116,6 +114,7 @@
 static struct context_vec *context_vec_end;
 static struct context_vec *context_vec_ptr;
 
+
 static void print_only(const char *path, size_t dirlen, const char *entry)
 {
 	if (dirlen > 1)
@@ -123,6 +122,7 @@
 	printf("Only in %.*s: %s\n", (int) dirlen, path, entry);
 }
 
+
 static void print_status(int val, char *path1, char *path2, char *entry)
 {
 	const char *const _entry = entry ? entry : "";
@@ -140,20 +140,20 @@
 		printf("Binary files %s and %s differ\n", _path1, _path2);
 		break;
 	case D_DIFFER:
-		if (cmd_flags & FLAG_q)
+		if (option_mask32 & FLAG_q)
 			printf("Files %s and %s differ\n", _path1, _path2);
 		break;
 	case D_SAME:
-		if (cmd_flags & FLAG_s)
+		if (option_mask32 & FLAG_s)
 			printf("Files %s and %s are identical\n", _path1, _path2);
 		break;
 	case D_MISMATCH1:
-		printf("File %s is a directory while file %s is a regular file\n",
-			   _path1, _path2);
+		printf("File %s is a %s while file %s is a %s\n",
+			   _path1, "directory", _path2, "regular file");
 		break;
 	case D_MISMATCH2:
-		printf("File %s is a regular file while file %s is a directory\n",
-			   _path1, _path2);
+		printf("File %s is a %s while file %s is a %s\n",
+			   _path1, "regular file", _path2, "directory");
 		break;
 	case D_SKIPPED1:
 		printf("File %s is not a regular file or directory and was skipped\n",
@@ -170,6 +170,7 @@
 	}
 }
 
+
 /*
  * Hash function taken from Robert Sedgewick, Algorithms in C, 3d ed., p 578.
  */
@@ -180,7 +181,7 @@
 
 	sum = 1;
 	space = 0;
-	if (!(cmd_flags & FLAG_b) && !(cmd_flags & FLAG_w)) {
+	if (!(option_mask32 & FLAG_b) && !(option_mask32 & FLAG_w)) {
 		if (FLAG_i)
 			for (i = 0; (t = getc(f)) != '\n'; i++) {
 				if (t == EOF) {
@@ -209,7 +210,7 @@
 				space++;
 				continue;
 			default:
-				if (space && !(cmd_flags & FLAG_w)) {
+				if (space && !(option_mask32 & FLAG_w)) {
 					i++;
 					space = 0;
 				}
@@ -234,22 +235,20 @@
 }
 
 
-
 /*
  * Check to see if the given files differ.
  * Returns 0 if they are the same, 1 if different, and -1 on error.
  */
 static int files_differ(FILE * f1, FILE * f2, int flags)
 {
-	char buf1[BUFSIZ], buf2[BUFSIZ];
 	size_t i, j;
 
 	if ((flags & (D_EMPTY1 | D_EMPTY2)) || stb1.st_size != stb2.st_size ||
 		(stb1.st_mode & S_IFMT) != (stb2.st_mode & S_IFMT))
 		return 1;
 	while (1) {
-		i = fread(buf1, 1, sizeof(buf1), f1);
-		j = fread(buf2, 1, sizeof(buf2), f2);
+		i = fread(bb_common_bufsiz1,            1, BUFSIZ/2, f1);
+		j = fread(bb_common_bufsiz1 + BUFSIZ/2, 1, BUFSIZ/2, f2);
 		if (i != j)
 			return 1;
 		if (i == 0 && j == 0) {
@@ -257,11 +256,13 @@
 				return 1;
 			return 0;
 		}
-		if (memcmp(buf1, buf2, i) != 0)
+		if (memcmp(bb_common_bufsiz1,
+		           bb_common_bufsiz1 + BUFSIZ/2, i) != 0)
 			return 1;
 	}
 }
 
+
 static void prepare(int i, FILE * fd, off_t filesize)
 {
 	struct line *p;
@@ -286,6 +287,7 @@
 	file[i] = p;
 }
 
+
 static void prune(void)
 {
 	int i, j;
@@ -303,6 +305,7 @@
 	}
 }
 
+
 static void equiv(struct line *a, int n, struct line *b, int m, int *c)
 {
 	int i, j;
@@ -330,6 +333,7 @@
 	c[j] = -1;
 }
 
+
 static int isqrt(int n)
 {
 	int y, x = 1;
@@ -347,6 +351,7 @@
 	return x;
 }
 
+
 static int newcand(int x, int y, int pred)
 {
 	struct cand *q;
@@ -395,7 +400,7 @@
 
 #if ENABLE_FEATURE_DIFF_MINIMAL
 	const unsigned int bound =
-		(cmd_flags & FLAG_d) ? UINT_MAX : MAX(256, isqrt(n));
+		(option_mask32 & FLAG_d) ? UINT_MAX : MAX(256, isqrt(n));
 #else
 	const unsigned int bound = MAX(256, isqrt(n));
 #endif
@@ -433,6 +438,7 @@
 	return k;
 }
 
+
 static void unravel(int p)
 {
 	struct cand *q;
@@ -457,6 +463,7 @@
 	free(a);
 }
 
+
 static int skipline(FILE * f)
 {
 	int i, c;
@@ -493,8 +500,8 @@
 			ixnew[j] = ctnew += skipline(f2);
 			j++;
 		}
-		if ((cmd_flags & FLAG_b) || (cmd_flags & FLAG_w)
-			|| (cmd_flags & FLAG_i)) {
+		if ((option_mask32 & FLAG_b) || (option_mask32 & FLAG_w)
+			|| (option_mask32 & FLAG_i)) {
 			while (1) {
 				c = getc(f1);
 				d = getc(f2);
@@ -502,13 +509,13 @@
 				 * GNU diff ignores a missing newline
 				 * in one file if bflag || wflag.
 				 */
-				if (((cmd_flags & FLAG_b) || (cmd_flags & FLAG_w)) &&
+				if (((option_mask32 & FLAG_b) || (option_mask32 & FLAG_w)) &&
 					((c == EOF && d == '\n') || (c == '\n' && d == EOF))) {
 					break;
 				}
 				ctold++;
 				ctnew++;
-				if ((cmd_flags & FLAG_b) && isspace(c) && isspace(d)) {
+				if ((option_mask32 & FLAG_b) && isspace(c) && isspace(d)) {
 					do {
 						if (c == '\n')
 							break;
@@ -519,7 +526,7 @@
 							break;
 						ctnew++;
 					} while (isspace(d = getc(f2)));
-				} else if (cmd_flags & FLAG_w) {
+				} else if (option_mask32 & FLAG_w) {
 					while (isspace(c) && c != '\n') {
 						c = getc(f1);
 						ctold++;
@@ -565,6 +572,7 @@
 		ixnew[j] = ctnew += skipline(f2);
 }
 
+
 /* shellsort CACM #201 */
 static void sort(struct line *a, int n)
 {
@@ -607,6 +615,7 @@
 		printf("%d,0", b);
 }
 
+
 static int fetch(long *f, int a, int b, FILE * lb, int ch)
 {
 	int i, j, c, lastc, col, nc;
@@ -618,7 +627,7 @@
 		nc = f[i] - f[i - 1];
 		if (ch != '\0') {
 			putchar(ch);
-			if (cmd_flags & FLAG_T)
+			if (option_mask32 & FLAG_T)
 				putchar('\t');
 		}
 		col = 0;
@@ -627,7 +636,7 @@
 				puts("\n\\ No newline at end of file");
 				return 0;
 			}
-			if (c == '\t' && (cmd_flags & FLAG_t)) {
+			if (c == '\t' && (option_mask32 & FLAG_t)) {
 				do {
 					putchar(' ');
 				} while (++col & 7);
@@ -640,21 +649,22 @@
 	return 0;
 }
 
+
 static int asciifile(FILE * f)
 {
 #if ENABLE_FEATURE_DIFF_BINARY
-	unsigned char buf[BUFSIZ];
 	int i, cnt;
 #endif
 
-	if ((cmd_flags & FLAG_a) || f == NULL)
+	if ((option_mask32 & FLAG_a) || f == NULL)
 		return 1;
 
 #if ENABLE_FEATURE_DIFF_BINARY
 	rewind(f);
-	cnt = fread(buf, 1, sizeof(buf), f);
+	cnt = fread(bb_common_bufsiz1, 1, BUFSIZ, f);
 	for (i = 0; i < cnt; i++) {
-		if (!isprint(buf[i]) && !isspace(buf[i])) {
+		if (!isprint(bb_common_bufsiz1[i])
+		 && !isspace(bb_common_bufsiz1[i])) {
 			return 0;
 		}
 	}
@@ -662,6 +672,7 @@
 	return 1;
 }
 
+
 /* dump accumulated "unified" diff changes */
 static void dump_unified_vec(FILE * f1, FILE * f2)
 {
@@ -735,10 +746,9 @@
 }
 
 
-
 /*
  * Indicate that there is a difference between lines a and b of the from file
- * to get to lines c to d of the to file.  If a is greater then b then there
+ * to get to lines c to d of the to file.  If a is greater than b then there
  * are no lines in the from file involved and this means that there were
  * lines appended (beginning at b).  If c is greater than d then there are
  * lines missing from the to file.
@@ -748,10 +758,10 @@
 {
 	static size_t max_context = 64;
 
-	if (a > b && c > d)
+	if ((a > b && c > d) || (option_mask32 & FLAG_q)) {
+		anychange = 1;
 		return;
-	if (cmd_flags & FLAG_q)
-		return;
+	}
 
 	/*
 	 * Allocate change records as needed.
@@ -771,7 +781,6 @@
 		 * Print the context/unidiff header first time through.
 		 */
 		print_header(file1, file2);
-		anychange = 1;
 	} else if (a > context_vec_ptr->b + (2 * context) + 1 &&
 			   c > context_vec_ptr->d + (2 * context) + 1) {
 		/*
@@ -785,14 +794,12 @@
 	context_vec_ptr->b = b;
 	context_vec_ptr->c = c;
 	context_vec_ptr->d = d;
-	return;
-
+	anychange = 1;
 }
 
 
 static void output(char *file1, FILE * f1, char *file2, FILE * f2)
 {
-
 	/* Note that j0 and j1 can't be used as they are defined in math.h.
 	 * This also allows the rather amusing variable 'j00'... */
 	int m, i0, i1, j00, j01;
@@ -816,7 +823,7 @@
 	if (m == 0) {
 		change(file1, f1, file2, f2, 1, 0, 1, len[1]);
 	}
-	if (anychange != 0) {
+	if (anychange != 0 && !(option_mask32 & FLAG_q)) {
 		dump_unified_vec(f1, f2);
 	}
 }
@@ -883,7 +890,6 @@
  *      3*(number of k-candidates installed),  typically about
  *      6n words for files of length n.
  */
-
 static int diffreg(char *ofile1, char *ofile2, int flags)
 {
 	char *file1 = ofile1;
@@ -901,25 +907,20 @@
 	if (strcmp(file1, "-") == 0 && strcmp(file2, "-") == 0)
 		goto closem;
 
+	f1 = stdin;
 	if (flags & D_EMPTY1)
 		f1 = xfopen(bb_dev_null, "r");
-	else {
-		if (strcmp(file1, "-") == 0)
-			f1 = stdin;
-		else
-			f1 = xfopen(file1, "r");
-	}
+	else if (file1[0] != '-' || file1[1]) /* not "-" */
+		f1 = xfopen(file1, "r");
 
+	f2 = stdin;
 	if (flags & D_EMPTY2)
 		f2 = xfopen(bb_dev_null, "r");
-	else {
-		if (strcmp(file2, "-") == 0)
-			f2 = stdin;
-		else
-			f2 = xfopen(file2, "r");
-	}
+	else if (file2[0] != '-' || file2[1]) /* not "-" */
+		f2 = xfopen(file2, "r");
 
-	if ((i = files_differ(f1, f2, flags)) == 0)
+	i = files_differ(f1, f2, flags);
+	if (i == 0)
 		goto closem;
 	else if (i != 1) {	/* 1 == ok */
 		/* error */
@@ -965,7 +966,7 @@
 	check(f1, f2);
 	output(file1, f1, file2, f2);
 
-  closem:
+ closem:
 	if (anychange) {
 		status |= 1;
 		if (rval == D_SAME)
@@ -982,10 +983,10 @@
 	return rval;
 }
 
+
 #if ENABLE_FEATURE_DIFF_DIR
 static void do_diff(char *dir1, char *path1, char *dir2, char *path2)
 {
-
 	int flags = D_HEADER;
 	int val;
 
@@ -1023,14 +1024,15 @@
 }
 #endif
 
+
 #if ENABLE_FEATURE_DIFF_DIR
 static int dir_strcmp(const void *p1, const void *p2)
 {
 	return strcmp(*(char *const *) p1, *(char *const *) p2);
 }
 
+
 /* This function adds a filename to dl, the directory listing. */
-
 static int add_to_dirlist(const char *filename,
 		struct stat ATTRIBUTE_UNUSED * sb, void *userdata,
 		int depth ATTRIBUTE_UNUSED)
@@ -1038,7 +1040,7 @@
 	dl_count++;
 	dl = xrealloc(dl, dl_count * sizeof(char *));
 	dl[dl_count - 1] = xstrdup(filename);
-	if (cmd_flags & FLAG_r) {
+	if (option_mask32 & FLAG_r) {
 		int *pp = (int *) userdata;
 		int path_len = *pp + 1;
 
@@ -1047,10 +1049,10 @@
 	return TRUE;
 }
 
+
 /* This returns a sorted directory listing. */
 static char **get_dir(char *path)
 {
-
 	int i;
 	char **retval;
 
@@ -1068,7 +1070,7 @@
 	dl_count = 0;
 
 	/* Now fill dl with a listing. */
-	if (cmd_flags & FLAG_r)
+	if (option_mask32 & FLAG_r)
 		recursive_action(path, TRUE, TRUE, FALSE, add_to_dirlist, NULL,
 						 userdata, 0);
 	else {
@@ -1095,9 +1097,9 @@
 	return retval;
 }
 
+
 static void diffdir(char *p1, char *p2)
 {
-
 	char **dirlist1, **dirlist2;
 	char *dp1, *dp2;
 	int dirlist1_count, dirlist2_count;
@@ -1144,13 +1146,13 @@
 			dirlist1++;
 			dirlist2++;
 		} else if (pos < 0) {
-			if (cmd_flags & FLAG_N)
+			if (option_mask32 & FLAG_N)
 				do_diff(p1, dp1, p2, NULL);
 			else
 				print_only(p1, strlen(p1) + 1, dp1);
 			dirlist1++;
 		} else {
-			if (cmd_flags & FLAG_N)
+			if (option_mask32 & FLAG_N)
 				do_diff(p1, NULL, p2, dp2);
 			else
 				print_only(p2, strlen(p2) + 1, dp2);
@@ -1161,7 +1163,6 @@
 #endif
 
 
-
 int diff_main(int argc, char **argv)
 {
 	int gotstdin = 0;
@@ -1170,10 +1171,11 @@
 	llist_t *L_arg = NULL;
 
 	opt_complementary = "L::";
-	cmd_flags = getopt32(argc, argv, "abdiL:NqrsS:tTU:wu",
+	getopt32(argc, argv, "abdiL:NqrsS:tTU:wu"
+			"p" /* ignored (for compatibility) */,
 			&L_arg, &start, &U_opt);
 
-	if (cmd_flags & FLAG_L) {
+	if (option_mask32 & FLAG_L) {
 		while (L_arg) {
 			if (label[0] == NULL)
 				label[0] = L_arg->data;
@@ -1196,8 +1198,8 @@
 	}
 
 	context = 3;		/* This is the default number of lines of context. */
-	if (cmd_flags & FLAG_U) {
-		context = xatoul_range(U_opt, 1, INT_MAX);
+	if (option_mask32 & FLAG_U) {
+		context = xatou_range(U_opt, 1, INT_MAX);
 	}
 	argc -= optind;
 	argv += optind;
@@ -1210,12 +1212,12 @@
 		bb_error_msg("missing filename");
 		bb_show_usage();
 	}
-	if (strcmp(argv[0], "-") == 0) {
+	if (argv[0][0] == '-' && !argv[0][1]) { /* "-" */
 		fstat(STDIN_FILENO, &stb1);
 		gotstdin = 1;
 	} else
 		xstat(argv[0], &stb1);
-	if (strcmp(argv[1], "-") == 0) {
+	if (argv[1][0] == '-' && !argv[1][1]) { /* "-" */
 		fstat(STDIN_FILENO, &stb2);
 		gotstdin = 1;
 	} else
@@ -1239,5 +1241,5 @@
 		}
 		print_status(diffreg(argv[0], argv[1], 0), argv[0], argv[1], NULL);
 	}
-	exit(status);
+	return status;
 }

Modified: trunk/busybox/libbb/last_char_is.c
===================================================================
--- trunk/busybox/libbb/last_char_is.c	2006-12-16 19:18:08 UTC (rev 16973)
+++ trunk/busybox/libbb/last_char_is.c	2006-12-16 22:18:44 UTC (rev 16974)
@@ -9,15 +9,15 @@
 
 #include "libbb.h"
 
-/* Find out if the last character of a string matches the one given Don't
- * underrun the buffer if the string length is 0.  Also avoids a possible
- * space-hogging inline of strlen() per usage.
+/* Find out if the last character of a string matches the one given.
+ * Don't underrun the buffer if the string length is 0.
  */
 char* last_char_is(const char *s, int c)
 {
-	if (s) {
-		s = strrchr(s, c);
-		if (s && !s[1])
+	if (s && *s) {
+		size_t sz = strlen(s) - 1;
+		s += sz;
+		if ( (unsigned char)*s == c)
 			return (char*)s;
 	}
 	return NULL;




More information about the busybox-cvs mailing list