mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-08-24 22:02:44 -06:00
ide: Display/apply patch tool in Assist
git-svn-id: svn://ultimatepp.org/upp/trunk@13482 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
parent
026d4ca1e6
commit
51904d3621
15 changed files with 605 additions and 218 deletions
|
|
@ -2,101 +2,168 @@
|
|||
|
||||
namespace Upp {
|
||||
|
||||
void PatchDiff::Copy(FileIn& in, FileIn& oin, int& l, int ln, int n)
|
||||
PatchDiff::PatchDiff()
|
||||
{
|
||||
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();
|
||||
Icon(DiffImg::PatchDiff());
|
||||
|
||||
hidden.Hide();
|
||||
|
||||
copyright.Hide();
|
||||
lfile.HSizePos();
|
||||
|
||||
copyleft.SetLabel("Patch");
|
||||
|
||||
files.WhenSel = [=] { File(); };
|
||||
|
||||
dir1.Ctrl::Remove();
|
||||
dir2.Ctrl::Remove();
|
||||
|
||||
int cy = patch_file.GetStdSize().cy;
|
||||
int div = Zy(4);
|
||||
files_pane.Add(target_dir.TopPos(0, cy).HSizePos());
|
||||
files_pane.Add(patch_file.TopPos(cy + div, cy).HSizePos());
|
||||
patch_file.SetReadOnly();
|
||||
target_dir.SetReadOnly();
|
||||
|
||||
seldir.Attach(target_dir);
|
||||
seldir.Title("Target directory");
|
||||
selfile.Attach(patch_file);
|
||||
selfile.Title("Patch file");
|
||||
selfile.Types("Patch files (*.diff *.patch)\t*.diff *.patch\nAll files\t*.*");
|
||||
|
||||
seldir.WhenSelected = selfile.WhenSelected = [=] {
|
||||
Open(~~patch_file, Vector<String>() << ~seldir);
|
||||
};
|
||||
|
||||
files_pane.Add(failed.TopPos(2 * cy + 2 * div, cy).HSizePos());
|
||||
|
||||
compare.SetLabel("Patch All");
|
||||
compare ^= [=] {
|
||||
String msg = "Patch everything?";
|
||||
if(failed_count)
|
||||
msg << "&[/ (" << failed_count << " files cannot be patched)";
|
||||
if(files.GetCount() == 0 || !PromptYesNo(msg))
|
||||
return;
|
||||
Progress pi("Patching", patch.GetCount());
|
||||
for(int i = 0; i < patch.GetCount(); i++) {
|
||||
if(pi.StepCanceled())
|
||||
return;
|
||||
String h = patch.GetPatchedFile(i);
|
||||
String p = patch.GetPath(i);
|
||||
if(!h.IsVoid())
|
||||
if(IsNull(h))
|
||||
FileDelete(p);
|
||||
else
|
||||
SaveFile(p, h);
|
||||
}
|
||||
Break(IDOK);
|
||||
};
|
||||
|
||||
copyleft ^= [=] {
|
||||
int ii = GetFileIndex();
|
||||
if(ii < 0 || !PromptYesNo("Patch [* \1" + file_path + "\1] ?") || patched_file.IsVoid())
|
||||
return;
|
||||
if(IsNull(patched_file))
|
||||
FileDelete(file_path);
|
||||
else
|
||||
SaveFile(file_path, patched_file);
|
||||
list[ii].d = 4;
|
||||
files.Set(files.GetCursor(), MakeFile(ii));
|
||||
File();
|
||||
};
|
||||
|
||||
Title("Patch");
|
||||
}
|
||||
|
||||
void PatchDiff::LoadDiff(const char *fn)
|
||||
bool PatchDiff::Open(const char *patch_path, const Vector<String>& target_dirs)
|
||||
{
|
||||
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);
|
||||
failed_count = 0;
|
||||
list.Clear();
|
||||
failed.Hide();
|
||||
ShowResult();
|
||||
patch_file <<= Null;
|
||||
target_dir <<= Null;
|
||||
|
||||
Progress pi;
|
||||
if(!patch.Load(patch_path, pi))
|
||||
return false;
|
||||
|
||||
if(!patch.MatchFiles(target_dirs, pi))
|
||||
return false;
|
||||
|
||||
String target_dir = patch.GetTargetDir();
|
||||
|
||||
patch_file <<= patch_path;
|
||||
this->target_dir <<= target_dir;
|
||||
|
||||
list.Clear();
|
||||
pi.SetText("Checking files");
|
||||
pi.SetTotal(patch.GetCount());
|
||||
for(int i = 0; i < patch.GetCount(); i++) {
|
||||
if(pi.StepCanceled())
|
||||
return false;
|
||||
String fn = patch.GetFile(i);
|
||||
String p = patch.GetPath(i);
|
||||
String h = patch.GetPatchedFile(i);
|
||||
bool pe = h.GetCount();
|
||||
bool x = FileExists(p);
|
||||
bool failed = h.IsVoid();
|
||||
list.Add(MakeTuple(fn, p, p, failed ? 3 : pe && x ? 0 : pe ? 2 : 1));
|
||||
if(failed)
|
||||
failed_count++;
|
||||
}
|
||||
|
||||
failed.Show(failed_count);
|
||||
failed.SetInk(SRed()).SetFont(StdFont().Bold().Italic());
|
||||
failed = String() << failed_count << " file(s) cannot be patched";
|
||||
|
||||
ShowResult();
|
||||
|
||||
if(files.GetCount())
|
||||
files.SetCursor(0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void PatchDiff::Open()
|
||||
int PatchDiff::GetFileIndex() const
|
||||
{
|
||||
if(!DiffFs().ExecuteOpen())
|
||||
return;
|
||||
String f = ~DiffFs();
|
||||
r <<= f;
|
||||
LoadDiff(f);
|
||||
diff.Set(LoadFile(editfile), extfile);
|
||||
int ii = files.GetCursor();
|
||||
return ii >= 0 ? files.Get(ii).data : -1;
|
||||
}
|
||||
|
||||
void PatchDiff::File()
|
||||
{
|
||||
diff.Set(Null, Null);
|
||||
String p2;
|
||||
String op = " [PATCHED]";
|
||||
copyleft.Disable();
|
||||
file_path.Clear();
|
||||
patched_file.Clear();
|
||||
int ii = GetFileIndex();
|
||||
if(ii >= 0) {
|
||||
file_path = patch.GetPath(ii);
|
||||
if(GetFileLength(file_path) < 4 * 1024 * 1024) {
|
||||
String content = LoadFile(file_path);
|
||||
if(list[ii].d == PATCHED_FILE) {
|
||||
p2 = "[FILE IS PATCHED]";
|
||||
diff.Set(content, content);
|
||||
}
|
||||
else {
|
||||
patched_file = patch.GetPatchedFile(ii);
|
||||
if(patched_file.IsVoid()) {
|
||||
diff.Set(content, patch.GetPatch(ii));
|
||||
p2 = "[FAILED TO APPLY THE PATCH]";
|
||||
}
|
||||
else {
|
||||
diff.Set(content, patched_file);
|
||||
p2 = file_path + " [PATCHED]";
|
||||
copyleft.Enable();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
lfile <<= file_path;
|
||||
rfile <<= p2;
|
||||
}
|
||||
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue