Last active
August 29, 2015 14:27
-
-
Save ynkdir/82624093bd2274de86a3 to your computer and use it in GitHub Desktop.
abcdiff(仮)
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
// cl /Idtl abcdiff.cpp | |
// https://github.com/cubicdaiya/dtl | |
#include <dtl/dtl.hpp> | |
#include <iostream> | |
#include <fstream> | |
#include <sstream> | |
#include <vector> | |
#include <string> | |
#include <time.h> | |
#include <sys/stat.h> | |
using namespace std; | |
using dtl::Diff; | |
using dtl::elemInfo; | |
using dtl::uniHunk; | |
struct normalHunk { | |
int oldstart; | |
int oldcount; | |
int newstart; | |
int newcount; | |
}; | |
static bool isFileExist(string& fs); | |
static void showStats (string fp1, string fp2); | |
static void unifiedDiff (string fp1, string fp2); | |
static void normalDiff (string fp1, string fp2); | |
static bool isFileExist(string& fs) | |
{ | |
FILE *fp; | |
if ((fp = fopen(fs.c_str(), "r")) == NULL) { | |
return false; | |
} | |
fclose(fp); | |
return true; | |
} | |
static void showStats (string fp1, string fp2) | |
{ | |
const int MAX_LENGTH = 255; | |
char time_format[] = "%Y-%m-%d %H:%M:%S %z"; | |
time_t rawtime[2]; | |
struct tm *timeinfo[2]; | |
struct stat st[2]; | |
if (stat(fp1.c_str(), &st[0]) == -1) { | |
cerr << "argv1 is invalid." << endl; | |
exit(-1); | |
} | |
if (stat(fp2.c_str(), &st[1]) == -1) { | |
cerr << "argv2 is invalid" << endl; | |
exit(-1); | |
} | |
char buf[2][MAX_LENGTH + 1]; | |
rawtime[0] = st[0].st_mtime; | |
timeinfo[0] = localtime(&rawtime[0]); | |
strftime(buf[0], MAX_LENGTH, time_format, timeinfo[0]); | |
cout << "--- " << fp1 << '\t' << buf[0] << endl; | |
rawtime[1] = st[1].st_mtime; | |
timeinfo[1] = localtime(&rawtime[1]); | |
strftime(buf[1], MAX_LENGTH, time_format, timeinfo[1]); | |
cout << "+++ " << fp2 << '\t' << buf[1] << endl; | |
} | |
static void unifiedDiff (string fp1, string fp2) | |
{ | |
typedef string elem; | |
typedef vector< elem > sequence; | |
typedef pair< elem, elemInfo > sesElem; | |
ifstream Aifs(fp1.c_str()); | |
ifstream Bifs(fp2.c_str()); | |
elem buf; | |
sequence ALines, BLines; | |
while(getline(Aifs, buf)){ | |
ALines.push_back(buf); | |
} | |
while(getline(Bifs, buf)){ | |
BLines.push_back(buf); | |
} | |
Diff< elem > diff(ALines, BLines); | |
diff.onHuge(); | |
//diff.onUnserious(); | |
diff.compose(); | |
// type unihunk definition test | |
uniHunk< sesElem > hunk; | |
if (diff.getEditDistance() > 0) { | |
showStats(fp1, fp2); // show file info | |
} | |
diff.composeUnifiedHunks(); | |
diff.printUnifiedFormat(); | |
} | |
static void normalDiff (string fp1, string fp2) | |
{ | |
typedef string elem; | |
typedef vector< elem > sequence; | |
typedef pair< elem, elemInfo > sesElem; | |
ifstream Aifs(fp1.c_str()); | |
ifstream Bifs(fp2.c_str()); | |
elem buf; | |
sequence ALines, BLines; | |
while(getline(Aifs, buf)){ | |
ALines.push_back(buf); | |
} | |
while(getline(Bifs, buf)){ | |
BLines.push_back(buf); | |
} | |
Diff< elem > diff(ALines, BLines); | |
diff.onHuge(); | |
//diff.onUnserious(); | |
diff.compose(); | |
vector<normalHunk> hunks; | |
// composeNormalHunks | |
{ | |
int i = 0; | |
int a = 0; | |
int b = 0; | |
normalHunk h; | |
auto seq = diff.getSes().getSequence(); | |
while (i < seq.size()) { | |
switch (seq[i].second.type) { | |
case dtl::SES_COMMON: | |
++i; | |
++a; | |
++b; | |
break; | |
case dtl::SES_ADD: | |
h.oldstart = a; | |
h.oldcount = 0; | |
h.newstart = b; | |
h.newcount = 0; | |
while (i < seq.size() && seq[i].second.type == dtl::SES_ADD) { | |
++b; | |
++h.newcount; | |
++i; | |
} | |
while (i < seq.size() && seq[i].second.type == dtl::SES_DELETE) { | |
++a; | |
++h.oldcount; | |
++i; | |
} | |
hunks.push_back(h); | |
break; | |
case dtl::SES_DELETE: | |
h.oldstart = a; | |
h.oldcount = 0; | |
h.newstart = b; | |
h.newcount = 0; | |
while (i < seq.size() && seq[i].second.type == dtl::SES_DELETE) { | |
++a; | |
++h.oldcount; | |
++i; | |
} | |
while (i < seq.size() && seq[i].second.type == dtl::SES_ADD) { | |
++b; | |
++h.newcount; | |
++i; | |
} | |
hunks.push_back(h); | |
break; | |
} | |
} | |
} | |
// printNormalFormat | |
{ | |
int base = 1; | |
stringstream ss; | |
string oldrange; | |
string newrange; | |
for (auto h : hunks) { | |
ss.str(""); | |
if (h.oldcount == 0) { | |
ss << h.oldstart; | |
} else if (h.oldcount == 1) { | |
ss << (h.oldstart + base); | |
} else { | |
ss << (h.oldstart + base) << "," << (h.oldstart + base + h.oldcount - 1); | |
} | |
oldrange = ss.str(); | |
ss.str(""); | |
if (h.newcount == 0) { | |
ss << h.newstart; | |
} else if (h.newcount == 1) { | |
ss << (h.newstart + base); | |
} else { | |
ss << (h.newstart + base) << "," << (h.newstart + base + h.newcount - 1); | |
} | |
newrange = ss.str(); | |
if (h.oldcount == 0) { | |
cout << oldrange << "a" << newrange << endl; | |
for (int i = 0; i < h.newcount; ++i) { | |
cout << "> " << BLines[h.newstart + i] << endl; | |
} | |
} else if (h.newcount == 0) { | |
cout << oldrange << "d" << newrange << endl; | |
for (int i = 0; i < h.oldcount; ++i) { | |
cout << "< " << ALines[h.oldstart + i] << endl; | |
} | |
} else { | |
cout << oldrange << "c" << newrange << endl; | |
for (int i = 0; i < h.oldcount; ++i) { | |
cout << "< " << ALines[h.oldstart + i] << endl; | |
} | |
cout << "---" << endl; | |
for (int i = 0; i < h.newcount; ++i) { | |
cout << "> " << BLines[h.newstart + i] << endl; | |
} | |
} | |
} | |
} | |
} | |
int main(int argc, char *argv[]) | |
{ | |
if (argc < 3) { | |
cerr << "Too few arguments." << endl; | |
return -1; | |
} | |
string s1(argv[1]); | |
string s2(argv[2]); | |
bool fileExist = true; | |
if (!isFileExist(s1)) { | |
cerr << s1 << " is invalid." << endl; | |
fileExist = false; | |
} | |
if (!isFileExist(s2)) { | |
cerr << s2 << " is invalid." << endl; | |
fileExist = false; | |
} | |
if (!fileExist) { | |
return -1; | |
} | |
normalDiff(s1, s2); | |
return 0; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment