#include "TextDiffCtrl.h" namespace Upp { void PatchDiff::Copy(FileIn& in, FileIn& oin, int& l, int ln, int n) { if(ln < l) throw CParser::Error(""); while(l < ln) { if(oin.IsEof()) throw CParser::Error(""); extfile << oin.GetLine() << "\r\n"; l++; } l += n; while(n--) oin.GetLine(); } void PatchDiff::LoadDiff(const char *fn) { try { FileIn in(fn); FileIn oin(editfile); extfile.Clear(); int l = 1; String s = in.GetLine(); if(IsDigit(*s)) { in.Seek(0); while(!in.IsEof()) { s = in.GetLine(); if(IsDigit(*s)) { CParser p(s); int ln = p.ReadNumber(); int n = 0; if(p.Char('a')) ln++; else { n = p.Char(',') ? p.ReadNumber() - ln + 1 : 1; if(!p.Char('c')) p.PassChar('d'); } Copy(in, oin, l, ln, n); } else if(*s == '>') { if(s[1] != ' ') throw CParser::Error(""); extfile << s.Mid(2) << "\r\n"; } else if(*s != '<' && *s != '-') throw CParser::Error(""); } } else { for(;;) { if(in.IsEof()) throw CParser::Error(""); if(in.GetLine().Mid(0, 4) == "+++ ") break; } while(!in.IsEof()) { String s = in.GetLine(); if(*s == '@') { CParser p(s); p.PassChar2('@', '@'); p.PassChar('-'); int ln = p.ReadNumber(); int n = 1; if(p.Char(',')) n = p.ReadNumber(); Copy(in, oin, l, ln, n); } else if(*s == '+' || *s == ' ') extfile << s.Mid(1) << "\r\n"; else if(*s != '-') throw CParser::Error(""); } } while(!oin.IsEof()) extfile << oin.GetLine() << "\r\n"; } catch(CParser::Error&) { Exclamation("Invalid file format!"); extfile = LoadFile(fn); } } void PatchDiff::Open() { if(!DiffFs().ExecuteOpen()) return; String f = ~DiffFs(); r <<= f; LoadDiff(f); diff.Set(LoadFile(editfile), extfile); } };