summaryrefslogtreecommitdiff
path: root/usr.bin/mg/buffer.c
diff options
context:
space:
mode:
authorFlorian Obser <florian@cvs.openbsd.org>2012-12-27 18:51:53 +0000
committerFlorian Obser <florian@cvs.openbsd.org>2012-12-27 18:51:53 +0000
commit3b818e35b917be29e9bea7603fbe7c6d65b2537f (patch)
tree7fc19af2733c971d9aebbfa7a5d366afbc64c5e5 /usr.bin/mg/buffer.c
parent5bdbfcba5ec91acae15976c6c3c6008887b9de6a (diff)
diff-buffer-with-file
input gsoares@, Sunil Nimmagadda, jasper@ ok jasper@, benno@
Diffstat (limited to 'usr.bin/mg/buffer.c')
-rw-r--r--usr.bin/mg/buffer.c77
1 files changed, 76 insertions, 1 deletions
diff --git a/usr.bin/mg/buffer.c b/usr.bin/mg/buffer.c
index 0b16af1f737..0b590ebbfd8 100644
--- a/usr.bin/mg/buffer.c
+++ b/usr.bin/mg/buffer.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: buffer.c,v 1.87 2012/11/06 18:04:10 florian Exp $ */
+/* $OpenBSD: buffer.c,v 1.88 2012/12/27 18:51:52 florian Exp $ */
/* This file is in the public domain. */
@@ -12,6 +12,10 @@
#include <libgen.h>
#include <stdarg.h>
+#ifndef DIFFTOOL
+#define DIFFTOOL "/usr/bin/diff"
+#endif /* !DIFFTOOL */
+
static struct buffer *makelist(void);
static struct buffer *bnew(const char *);
@@ -920,3 +924,74 @@ dorevert(void)
return(setlineno(lineno));
return (FALSE);
}
+
+/*
+ * Diff the current buffer to what is on disk.
+ */
+/*ARGSUSED */
+int
+diffbuffer(int f, int n)
+{
+ struct buffer *bp;
+ struct line *lp, *lpend;
+ size_t len;
+ int ret;
+ char *text, *ttext;
+ char * const argv[] =
+ {DIFFTOOL, "-u", "-p", curbp->b_fname, "-", (char *)NULL};
+
+ len = 0;
+
+ /* C-u is not supported */
+ if (n > 1)
+ return (ABORT);
+
+ if (access(DIFFTOOL, X_OK) != 0) {
+ ewprintf("%s not found or not executable.", DIFFTOOL);
+ return (FALSE);
+ }
+
+ if (curbp->b_fname[0] == 0) {
+ ewprintf("Cannot diff buffer not associated with any files.");
+ return (FALSE);
+ }
+
+ lpend = curbp->b_headp;
+ for (lp = lforw(lpend); lp != lpend; lp = lforw(lp)) {
+ len+=llength(lp);
+ if (lforw(lp) != lpend) /* no implied \n on last line */
+ len++;
+ }
+ if ((text = calloc(len + 1, sizeof(char))) == NULL) {
+ ewprintf("Cannot allocate memory.");
+ return (FALSE);
+ }
+ ttext = text;
+
+ for (lp = lforw(lpend); lp != lpend; lp = lforw(lp)) {
+ if (llength(lp) != 0) {
+ memcpy(ttext, ltext(lp), llength(lp));
+ ttext += llength(lp);
+ }
+ if (lforw(lp) != lpend) /* no implied \n on last line */
+ *ttext++ = '\n';
+ }
+
+ bp = bfind("*Diff*", TRUE);
+ bp->b_flag |= BFREADONLY;
+ if (bclear(bp) != TRUE) {
+ free(text);
+ return (FALSE);
+ }
+
+ ret = pipeio(DIFFTOOL, argv, text, len, bp);
+
+ if (ret == TRUE) {
+ eerase();
+ if (lforw(bp->b_headp) == bp->b_headp)
+ addline(bp, "Diff finished (no differences).");
+ }
+
+ free(text);
+ return (ret);
+}