commit - cd25827e24b8fad0a3f4a89b72fbdba86bc2c5d1
commit + 732e8ee0325715558a17b919a7f6a16bf64d66e3
blob - 7846e5688b5f703b6d8d58917d7050d3174b578a
blob + 18dd0286fe53d332f4c991dc64386cf6d2a55003
--- diff/diff.c
+++ diff/diff.c
#endif
__dead void usage(void);
-int diffreg(char *, char *, int);
+int diffreg(char *, char *, bool, bool);
int openfile(const char *, char **, struct stat *);
__dead void
usage(void)
{
fprintf(stderr,
- "usage: %s [-p] file1 file2\n"
+ "usage: %s [-pw] file1 file2\n"
"\n"
" -p Use Patience Diff (slower but often nicer)\n"
+ " -w Ignore Whitespace\n"
, getprogname());
exit(1);
}
-static bool do_patience = false;
-
int
main(int argc, char *argv[])
{
int ch, rc;
+ bool do_patience = false, ignore_whitespace = false;
- while ((ch = getopt(argc, argv, "p")) != -1) {
+ while ((ch = getopt(argc, argv, "pw")) != -1) {
switch (ch) {
case 'p':
do_patience = true;
break;
+ case 'w':
+ ignore_whitespace = true;
+ break;
default:
usage();
}
if (argc != 2)
usage();
- rc = diffreg(argv[0], argv[1], 0);
+ rc = diffreg(argv[0], argv[1], do_patience, ignore_whitespace);
if (rc != DIFF_RC_OK) {
fprintf(stderr, "diff: %s\n", strerror(rc));
return 1;
};
int
-diffreg(char *file1, char *file2, int flags)
+diffreg(char *file1, char *file2, bool do_patience, bool ignore_whitespace)
{
char *str1, *str2;
int fd1, fd2;
fd1 = openfile(file1, &str1, &st1);
fd2 = openfile(file2, &str2, &st2);
- result = diff_main(cfg, fd1, str1, st1.st_size, fd2, str2, st2.st_size);
+ result = diff_main(cfg, fd1, str1, st1.st_size, fd2, str2, st2.st_size,
+ ignore_whitespace);
#if 0
rc = diff_output_plain(stdout, &info, result);
#else
blob - 6397e0c1d52b5e01b3f3e1df122ace240efe2bf2
blob + 5d87a63c1fcbe06352062094f2bd48b70b86f1d4
--- include/diff/diff_main.h
+++ include/diff/diff_main.h
ARRAYLIST(struct diff_atom) atoms;
struct diff_data *root;
+
+ bool ignore_whitespace;
};
void diff_data_free(struct diff_data *diff_data);
int left_fd, const uint8_t *left_data,
off_t left_len,
int right_fd, const uint8_t *right_data,
- off_t right_len);
+ off_t right_len, bool ignore_whitespace);
void diff_result_free(struct diff_result *result);
blob - 84c41f39c99ce5bb1a20384b96c9cdc772b89ed6
blob + 840d4e7718250a86e04d1ac09b88ca3d5f7f6927
--- lib/diff_main.c
+++ lib/diff_main.c
#include <sys/queue.h>
+#include <ctype.h>
#include <errno.h>
#include <stdint.h>
#include <stdlib.h>
static int
buf_cmp(const unsigned char *left, size_t left_len,
- const unsigned char *right, size_t right_len)
+ const unsigned char *right, size_t right_len,
+ bool ignore_whitespace)
{
- int cmp = memcmp(left, right, MIN(left_len, right_len));
+ int cmp;
+
+ if (ignore_whitespace) {
+ int il = 0, ir = 0;
+ while (il < left_len && ir < right_len) {
+ unsigned char cl = left[il];
+ unsigned char cr = right[ir];
+
+ if (isspace(cl) && il < left_len) {
+ il++;
+ continue;
+ }
+ if (isspace(cr) && ir < right_len) {
+ ir++;
+ continue;
+ }
+
+ if (cl > cr)
+ return 1;
+ if (cr > cl)
+ return -1;
+ il++;
+ ir++;
+ }
+ while (il < left_len) {
+ unsigned char cl = left[il++];
+ if (!isspace(cl))
+ return 1;
+ }
+ while (ir < right_len) {
+ unsigned char cr = right[ir++];
+ if (!isspace(cr))
+ return -1;
+ }
+
+ return 0;
+ }
+
+ cmp = memcmp(left, right, MIN(left_len, right_len));
if (cmp)
return cmp;
if (left_len == right_len)
const struct diff_atom *right)
{
off_t remain_left, remain_right;
+ bool ignore_whitespace;
+
+ ignore_whitespace = (left->d->root->ignore_whitespace ||
+ right->d->root->ignore_whitespace);
- if (!left->len && !right->len) {
- *cmp = 0;
- return 0;
- }
- if (!right->len) {
- *cmp = 1;
- return 0;
- }
- if (!left->len) {
- *cmp = -1;
- return 0;
+ if (!ignore_whitespace) {
+ if (!left->len && !right->len) {
+ *cmp = 0;
+ return 0;
+ }
+ if (!right->len) {
+ *cmp = 1;
+ return 0;
+ }
+ if (!left->len) {
+ *cmp = -1;
+ return 0;
+ }
}
if (left->at != NULL && right->at != NULL) {
- *cmp = buf_cmp(left->at, left->len, right->at, right->len);
+ *cmp = buf_cmp(left->at, left->len, right->at, right->len,
+ ignore_whitespace);
return 0;
}
p_right = right->at + (right->len - remain_right);
}
- r = buf_cmp(p_left, n_left, p_right, n_right);
+ r = buf_cmp(p_left, n_left, p_right, n_right,
+ ignore_whitespace);
if (r) {
*cmp = r;
return 0;
void
diff_data_init_root(struct diff_data *d, int fd, const uint8_t *data,
- unsigned long long len)
+ unsigned long long len, bool ignore_whitespace)
{
*d = (struct diff_data){
.fd = fd,
.data = data,
.len = len,
.root = d,
+ .ignore_whitespace = ignore_whitespace,
};
}
struct diff_result *
diff_main(const struct diff_config *config,
int left_fd, const uint8_t *left_data, off_t left_len,
- int right_fd, const uint8_t *right_data, off_t right_len)
+ int right_fd, const uint8_t *right_data, off_t right_len,
+ bool ignore_whitespace)
{
struct diff_result *result = malloc(sizeof(struct diff_result));
if (!result)
return NULL;
*result = (struct diff_result){};
- diff_data_init_root(&result->left, left_fd, left_data, left_len);
- diff_data_init_root(&result->right, right_fd, right_data, right_len);
+ diff_data_init_root(&result->left, left_fd, left_data, left_len,
+ ignore_whitespace);
+ diff_data_init_root(&result->right, right_fd, right_data, right_len,
+ ignore_whitespace);
if (!config->atomize_func) {
result->rc = EINVAL;
blob - /dev/null
blob + 139970c971d6d429a4e774640a0735e86fc0a7dd (mode 644)
--- /dev/null
+++ test/expect013.diff
+--- test013.left-w.txt
++++ test013.right-w.txt
+@@ -3,5 +3,5 @@
+ C
+ D
+ E
+-F
+-G
++F x
++y G
blob - 17f8df091e1bb71385f342f2e783b09347df7d75
blob + f2b8d42de7348bdf55fa8fa3e22691c387e77fd2
--- test/verify_all.sh
+++ test/verify_all.sh
orig_left="$1"
orig_right="$2"
the_diff="$3"
+ diff_opts="$4"
+ expected_diff="$5"
verify_left="verify.$orig_left"
verify_right="verify.$orig_right"
- if [ "x$diff_type" = "xunidiff" ]; then
+ if [ -n "$diff_opts" ]; then
+ if ! cmp "$got_diff" "$expected_diff" ; then
+ echo "FAIL: $got_diff != $expected_diff"
+ return 1
+ fi
+ elif [ "x$diff_type" = "xunidiff" ]; then
cp "$orig_left" "$verify_right"
patch --quiet -u "$verify_right" "$the_diff"
if ! cmp "$orig_right" "$verify_right" ; then
return 0
}
-for left in test*.left.* ; do
- right="$(echo "$left" | sed 's/\.left\./.right./')"
- expected_diff="$(echo "$left" | sed 's/test\([0-9]*\)\..*/expect\1.diff/')"
+for left in test*.left* ; do
+ right="$(echo "$left" | sed 's/\.left/\.right/')"
+ diff_opts="$(echo "$left" | sed 's/test[0-9]*\.left\([-a-zA-Z]*\).txt/\1/')"
+ expected_diff="$(echo "$left" | sed 's/test\([-0-9a-zA-Z]*\)\..*/expect\1.diff/')"
got_diff="verify.$expected_diff"
- "$diff_prog" "$left" "$right" > "$got_diff"
+ "$diff_prog" $diff_opts "$left" "$right" > "$got_diff"
set -e
- verify_diff_script "$left" "$right" "$got_diff"
+ verify_diff_script "$left" "$right" "$got_diff" "$diff_opts" "$expected_diff"
set +e
done
blob - /dev/null
blob + 53b3adf33dac5151d56547908cd6496798c80c3a (mode 644)
--- /dev/null
+++ test/test013.left-w.txt
+A
+B
+C
+D
+E
+F
+G
blob - /dev/null
blob + 1509b4b4fdfabbb8725d42c243b684c03fd1c1db (mode 644)
--- /dev/null
+++ test/test013.right-w.txt
+A
+ B
+C
+ D
+E
+F x
+y G