-
-
Save rikkimax/6ebef99d1d4ef56193a873096688b0ea to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| module diff; | |
| struct Diff { | |
| import std.utf : validate; | |
| import std.experimental.allocator : IAllocator, dispose, makeArray, expandArray; | |
| bool treatingAsBinary; | |
| ubyte[] diff; | |
| private { | |
| IAllocator alloc; | |
| } | |
| @disable this(this); | |
| ~this() { | |
| alloc.dispose(diffText); | |
| } | |
| this(IAllocator allocator, string filenameA, string filenameB, void[] fileA, void[] fileB) { | |
| alloc = allocator; | |
| try { | |
| validate(cast(char[])fileA); | |
| validate(cast(char[])fileB); | |
| } catch (Exception e) { | |
| // not valid | |
| treatingAsBinary = true; | |
| } | |
| if (treatingAsBinary) { | |
| foreach(DiffOperation op, const(void[]) value, size_t fileOffset; mba_impl(fileA, fileB)) { | |
| } | |
| } else { | |
| foreach(DiffOperation op, const(void[]) value, size_t fileOffset; mba_impl(fileA, fileB)) { | |
| } | |
| } | |
| } | |
| enum DiffOperation { | |
| Match, | |
| Removed, | |
| Inserted | |
| } | |
| private { | |
| auto mba_impl(void[] fileA, void[] fileB) { | |
| import mba.diff; | |
| import mba.varray; | |
| import mba.allocator; | |
| struct Result { | |
| int opApply(int delegate(DiffOperation op, const(void[]) value, size_t fileOffset) dg) { | |
| int result = 0; | |
| varray* ses = varray_new(diff_edit.sizeof, null); | |
| int d, sn; | |
| if ((d == diff(fileA.ptr, 0, cast(int)fileA.length, | |
| fileB.ptr, 0, cast(int)fileB.length, | |
| null, null, null, 0, ses, &sn, null)) == -1) { | |
| return -1; | |
| } | |
| F1: foreach(i; 0 .. sn) { | |
| diff_edit* e = cast(diff_edit*)varray_get(ses, i); | |
| final switch(e.op) { | |
| case diff_op.DIFF_MATCH: | |
| result = dg(DiffOperation.Match, cast(const(void[]))fileA[e.off .. e.off + e.len], e.off); | |
| if (result) | |
| break F1; | |
| break; | |
| case diff_op.DIFF_INSERT: | |
| result = dg(DiffOperation.Inserted, cast(const(void[]))fileB[e.off .. e.off + e.len], e.off); | |
| if (result) | |
| break F1; | |
| break; | |
| case diff_op.DIFF_DELETE: | |
| result = dg(DiffOperation.Removed, cast(const(void[]))fileA[e.off .. e.off + e.len], e.off); | |
| if (result) | |
| break F1; | |
| break; | |
| } | |
| } | |
| varray_deinit(ses); | |
| return result; | |
| } | |
| } | |
| return Result; | |
| } | |
| } | |
| } | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <stdlib.h> | |
| #include <string.h> | |
| #include <stdio.h> | |
| #include <errno.h> | |
| #include <mba/diff.h> | |
| #include <mba/msgno.h> | |
| int | |
| main(int argc, char *argv[]) | |
| { | |
| const char *a = argv[1]; | |
| const char *b = argv[2]; | |
| int n, m, d; | |
| int sn, i; | |
| struct varray *ses = varray_new(sizeof(struct diff_edit), NULL); | |
| if (argc < 3) { | |
| fprintf(stderr, "usage: %s <str1> <str2>\n", argv[0]); | |
| return EXIT_FAILURE; | |
| } | |
| n = strlen(a); | |
| m = strlen(b); | |
| if ((d = diff(a, 0, n, b, 0, m, NULL, NULL, NULL, 0, ses, &sn, NULL)) == -1) { | |
| MMNO(errno); | |
| return EXIT_FAILURE; | |
| } | |
| printf("d=%d sn=%d\n", d, sn); | |
| for (i = 0; i < sn; i++) { | |
| struct diff_edit *e = varray_get(ses, i); | |
| switch (e->op) { | |
| case DIFF_MATCH: | |
| printf("MAT: "); | |
| fwrite(a + e->off, 1, e->len, stdout); | |
| break; | |
| case DIFF_INSERT: | |
| printf("INS: "); | |
| fwrite(b + e->off, 1, e->len, stdout); | |
| break; | |
| case DIFF_DELETE: | |
| printf("DEL: "); | |
| fwrite(a + e->off, 1, e->len, stdout); | |
| break; | |
| } | |
| printf("\n"); | |
| } | |
| return EXIT_SUCCESS; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment