static void CollectPreBeginNote(PatchTask patchTask, SourceFile sourceFile, int currentLineId) { //read content of block //and also find int beginAtLine = currentLineId; //find end end block int j = sourceFile.LineCount; int i = beginAtLine - 1; //next line int count1 = 0; List <string> notes = new List <string>(); while (i >= 0 && count1 < 2) { string prevLine = sourceFile.GetLine(i).TrimStart(); //parse nextline for a command if (!string.IsNullOrEmpty(prevLine)) { if (prevLine.StartsWith("//###_")) { //stop break; } //this should be end context notes.Insert(0, prevLine); count1++; } i--; } patchTask.preNotes.AddRange(notes); //PRE }
static void CollectPostEndNote(PatchTask patchTask, SourceFile sourceFile, int currentLineId) { //read content of block //and also find int beginAtLine = currentLineId; //find end end block int j = sourceFile.LineCount; int i = beginAtLine + 1; //next line int count1 = 0; List <string> notes = new List <string>(); while (i < j && count1 < 2) { string nextLine = sourceFile.GetLine(i).TrimStart(); if (nextLine.StartsWith("//###")) { //stop break; } //parse nextline for a command if (!string.IsNullOrEmpty(nextLine)) { //this should be end context notes.Add(nextLine); count1++; } i++; } patchTask.postNotes.AddRange(notes); //POST }
public bool CheckIfFileWasPatched(SourceFile input, out string patchCode) { //check first line if (Path.GetFileName(input.Filename) == "CMakeLists.txt") { //this is cmake patchCode = "# PATCH "; input.IsCMakeFile = true; } else { patchCode = _ORIGINAL; } return(input.GetLine(0).StartsWith(patchCode)); }
public void PatchContent() { //1. check if file is exist string originalFilename = this.OriginalFileName; if (!File.Exists(originalFilename)) { throw new NotSupportedException("file not found!"); } SourceFile input = new SourceFile(originalFilename, false); input.ReadAllLines(); SourceFile output = new SourceFile(originalFilename, true); string patchCode; if (CheckIfFileWasPatched(input, out patchCode)) { //can't patch throw new NotSupportedException("not patch again in this file"); } else { //can patch **** //input patch code with original filename output.AddLine(patchCode + " " + originalFilename); } output.IsCMakeFile = input.IsCMakeFile; //----------------------------------------------------------------- //can't patch again int j = patchTasks.Count; for (int i = 0; i < j; ++i) { patchTasks[i].PatchFile(input, output); } int linecount = input.LineCount; for (int i = input.CurrentLine; i < linecount; ++i) { output.AddLine(input.GetLine(i)); input.CurrentLine++; } output.Save(); }
static int FindLineStartWith(SourceFile file, int startAt, string startWithStr) { int lineCount = file.LineCount; for (int i = startAt; i < lineCount; ++i) { string line = file.GetLine(i).TrimStart(); if (line.StartsWith(startWithStr)) { //found return(i); } } return(-1); //not found }
public void PatchFile(SourceFile input, SourceFile output) { //------------------------------------------------------------ if (this.IsPatchBlock) { throw new NotSupportedException(); } //------------------------------------------------------------ //find start position of this task int curLine = input.CurrentLine; int lineCount = input.LineCount; bool foundLandMark = false; int cur_line_id = curLine; for (; cur_line_id < lineCount; ++cur_line_id) { string line = input.GetLine(cur_line_id); input.CurrentLine++; if (line.TrimStart().StartsWith(this.LandMark)) { //found land mark foundLandMark = true; string newStartLine = PatchCommand.START + " " + this.TaskId; if (!string.IsNullOrEmpty(this.PatchStartCmd)) { newStartLine += " " + this.PatchStartCmd; } if (!output.IsCMakeFile) { output.AddLine(newStartLine); } if (this.PatchStartCmd == "-X") { //replace the original line with the land mark output.AddLine(this.LandMark); } else { output.AddLine(line); } break; } else { //just add to output output.AddLine(line); } } if (!foundLandMark) { //report System.Diagnostics.Debug.WriteLine("not completed :" + input.Filename + ", landmark: " + this.LandMark); return; throw new NotSupportedException(); } //------------------------------------------------------------ //do actions... int j = commands.Count; for (int c = 0; c < j; ++c) { PatchCommand cmd = commands[c]; //find start position switch (cmd.comandKind) { case PatchCommandKind.FindNextLandMark: { //from current position find next until found curLine = input.CurrentLine; bool foundNextLandMark = false; for (int i = curLine; i < lineCount; ++i) { string line = input.GetLine(i); input.CurrentLine++; if (line.TrimStart().StartsWith(cmd.String)) { //found land mark foundNextLandMark = true; AddControlLine(output, cmd); //*** output.AddLine(line); break; } else { //just add to output output.AddLine(line); } } if (!foundNextLandMark) { throw new NotSupportedException("next land mark not found"); } } break; case PatchCommandKind.AppendStringStart: { AddControlLine(output, cmd); //*** } break; case PatchCommandKind.FollowBy: { //just 1 line must match string nextLine = input.GetLine(input.CurrentLine); input.CurrentLine++; if (nextLine.TrimStart().StartsWith(cmd.String)) { //match AddControlLine(output, cmd); //*** output.AddLine(nextLine); } else { throw new NotSupportedException(); } } break; case PatchCommandKind.SkipUntilPass: { curLine = input.CurrentLine; bool foundNextLandMark = false; for (int i = curLine; i < lineCount; ++i) { string line = input.GetLine(i); input.CurrentLine++; if (line.TrimStart().StartsWith(cmd.String)) { AddControlLine(output, cmd); //*** //found land mark foundNextLandMark = true; //not add this //just skip break; } else { //skip } } if (!foundNextLandMark) { throw new NotSupportedException("next land mark not found"); } } break; case PatchCommandKind.SkipUntilAndAccept: { curLine = input.CurrentLine; bool foundNextLandMark = false; for (int i = curLine; i < lineCount; ++i) { string line = input.GetLine(i); input.CurrentLine++; if (line.TrimStart().StartsWith(cmd.String)) { //found land mark foundNextLandMark = true; //accept this line AddControlLine(output, cmd); //*** output.AddLine(line); break; } else { //skip } } if (!foundNextLandMark) { throw new NotSupportedException("next land mark not found"); } } break; default: throw new NotSupportedException(); } } }
/// <summary> /// create patch file from a patch file in disk /// </summary> /// <param name="filename"></param> /// <returns></returns> public static PatchFile BuildPatchFile(string filename) { //create patch command for specific filename PatchFile patchFile = new PatchFile(filename); SourceFile sourceFile = new SourceFile(filename, false); sourceFile.ReadAllLines(); int j = sourceFile.LineCount; if (j == 0) { return(null); } // PatchTask ptask = null; int i = 0; string line = sourceFile.GetLine(0); //first line is original filename string originalFilename; if (GetOriginalFilename(line, out originalFilename)) { //change origial file name for patch file patchFile.OriginalFileName = originalFilename; i++; //next line } for (; i < j; ++i) { line = sourceFile.GetLine(i).TrimStart(); //*** if (line.StartsWith("//###_")) { //what is the comamnd line = line.TrimEnd(); string cmdline; int taskId; string additionalInfo; ParseCommand(line, out cmdline, out taskId, out additionalInfo); switch (cmdline) { case PatchCommand.START: { //start new patch task //read next line for info i++; //read next line for land mark string cmd_value = sourceFile.GetLine(i); //create new task ptask = new PatchTask(cmd_value, taskId); ptask.Owner = patchFile; if (additionalInfo == "-X") //special cmd { ptask.PatchStartCmd = additionalInfo; } // patchFile.AddTask(ptask); } break; case PatchCommand.BEGIN: { //begin block *** //create new patch block ptask = new PatchTask("", taskId); //we will set land mark later ptask.Owner = patchFile; ptask.IsPatchBlock = true; patchFile.AddTask(ptask); ParseAutoContextPatchBlock(ptask, sourceFile, ref i); //parse auto context patch block } break; case PatchCommand.APPPEND_START: { //start collect append string //until find append_stop var collectAppendStBuilder = new StringBuilder(); i++; string cmd_value = sourceFile.GetLine(i); line = cmd_value.TrimStart(); //eval do { if (line.StartsWith(PatchCommand.APPPEND_STOP)) { //stop here break; } else { if (line.StartsWith("//###_")) { //other command throw new NotSupportedException(); } else { //collect this line collectAppendStBuilder.AppendLine(line); //read next line i++; line = sourceFile.GetLine(i).TrimStart(); } } } while (true); //finish command ptask.Append(collectAppendStBuilder.ToString()); } break; case PatchCommand.APPPEND_STOP: throw new NotSupportedException(); case PatchCommand.FIND_NEXT_LANDMARK: { i++; string cmd_value = sourceFile.GetLine(i); if (taskId != ptask.TaskId) { throw new NotSupportedException(); } ptask.FindNext(cmd_value); } break; case PatchCommand.FOLLOW_BY: { i++; string cmd_value = sourceFile.GetLine(i); if (taskId != ptask.TaskId) { throw new NotSupportedException(); } ptask.FollowBy(cmd_value); } break; case PatchCommand.SKIP_UNTIL_AND_ACCEPT: { i++; string cmd_value = sourceFile.GetLine(i); if (taskId != ptask.TaskId) { throw new NotSupportedException(); } ptask.SkipUntilAndAccept(cmd_value); } break; case PatchCommand.SKIP_UNTIL_PASS: { //has 2 parameters if (additionalInfo == null) { throw new NotSupportedException(); } // ptask.SkipUntilPass(additionalInfo); } break; default: throw new NotSupportedException(); } } } if (patchFile.TaskCount > 0) { return(patchFile); } else { return((ptask != null && ptask.CommandCount > 0) ? patchFile : null); } }
static void ParseAutoContextPatchBlock(PatchTask patchTask, SourceFile sourceFile, ref int currentLineId) { //read content of block //and also find int beginAtLine = currentLineId; //find end end block int i = beginAtLine + 1; //next line int j = sourceFile.LineCount; List <string> contentLines = new List <string>(); int foundPreNoteCount = 0; int foundPostNoteCount = 0; for (; i < j; ++i) { string line = sourceFile.GetLine(i).TrimStart(); //*** if (!line.StartsWith("//###_")) { contentLines.Add(line); } else { line = line.TrimEnd(); string cmdline; int taskId; string additionalInfo; ParseCommand(line, out cmdline, out taskId, out additionalInfo); switch (cmdline) { default: throw new NotSupportedException(); case PatchCommand.PRE: { i++; //read next line for PRE data patchTask.preNotes.Add(sourceFile.GetLine(i)); foundPreNoteCount++; } break; case PatchCommand.POST: { i++; patchTask.postNotes.Add(sourceFile.GetLine(i)); foundPostNoteCount++; } break; case PatchCommand.END: { //------ //find context of begin and end ** //1. begin context //2. post context //find proper land mark //read next line if (foundPreNoteCount == 0 && foundPostNoteCount == 0) { //find auto context CollectPreBeginNote(patchTask, sourceFile, beginAtLine); CollectPostEndNote(patchTask, sourceFile, i); } else { //use existing notes } patchTask.ContentLines = contentLines; currentLineId = i; return; } } } } currentLineId = i; }
public void PatchContent() { PatchingMsg = null; //1. check if file is exist string originalFilename = this.OriginalFileName; if (!File.Exists(originalFilename)) { throw new NotSupportedException("file not found!"); } SourceFile input = new SourceFile(originalFilename, false); input.ReadAllLines(); SourceFile output = new SourceFile(originalFilename, true); string patchCode; if (CheckIfFileWasPatched(input, out patchCode)) { //can't patch //throw new NotSupportedException("not patch again in this file"); PatchingMsg = this.OriginalFileName + " => has be patched, so skip this file"; return; } else { //can patch **** //input patch code with original filename output.AddLine(patchCode + " " + originalFilename); } output.IsCMakeFile = input.IsCMakeFile; //----------------------------------------------------------------- //other patch that is not block-patch int j = patchTasks.Count; for (int i = 0; i < j; ++i) { PatchTask ptask = patchTasks[i]; if (!ptask.IsPatchBlock) { ptask.PatchFile(input, output); } else { ptask.PatchBlockSouldStartAt = output.LineCount; } } int linecount = input.LineCount; for (int i = input.CurrentLine; i < linecount; ++i) { output.AddLine(input.GetLine(i)); input.CurrentLine++; } //----------------------------------------------------------------- //only block-patch for (int i = 0; i < j; ++i) { PatchTask ptask = patchTasks[i]; if (ptask.IsPatchBlock) { int newLineCount = ptask.PatchBlockFile(output); if (newLineCount == 1) { for (int n = i + 1; n < j; ++n) { //adjust new offset PatchTask p2 = patchTasks[n]; if (p2.IsPatchBlock) { p2.PatchBlockSouldStartAt += 1; } } } else { System.Diagnostics.Debug.WriteLine("output is not saved: " + ptask.Owner.OriginalFileName); return; } } } output.Save(); }
public void PatchFile(SourceFile input, SourceFile output) { //find start position of this task int curLine = input.CurrentLine; int lineCount = input.LineCount; bool foundLandMark = false; for (int i = curLine; i < lineCount; ++i) { string line = input.GetLine(i); input.CurrentLine++; if (line.TrimStart().StartsWith(this.LandMark)) { //found land mark foundLandMark = true; if (!output.IsCMakeFile) { output.AddLine(PatchCommand.START + " " + this.TaskId); } output.AddLine(line); break; } else { //just add to output output.AddLine(line); } } if (!foundLandMark) { return; throw new NotSupportedException(); } //------------------------------------------------------------ //do actions... int j = commands.Count; for (int c = 0; c < j; ++c) { PatchCommand cmd = commands[c]; //find start position switch (cmd.comandKind) { case PatchCommandKind.FindNextLandMark: { //from current position find next until found curLine = input.CurrentLine; bool foundNextLandMark = false; for (int i = curLine; i < lineCount; ++i) { string line = input.GetLine(i); input.CurrentLine++; if (line.TrimStart().StartsWith(cmd.String)) { //found land mark foundNextLandMark = true; AddControlLine(output, cmd); //*** output.AddLine(line); break; } else { //just add to output output.AddLine(line); } } if (!foundNextLandMark) { throw new NotSupportedException("next land mark not found"); } } break; case PatchCommandKind.AppendStringStart: { AddControlLine(output, cmd); //*** } break; case PatchCommandKind.FollowBy: { //just 1 line must match string nextLine = input.GetLine(input.CurrentLine); input.CurrentLine++; if (nextLine.TrimStart().StartsWith(cmd.String)) { //match AddControlLine(output, cmd); //*** output.AddLine(nextLine); } else { throw new NotSupportedException(); } } break; case PatchCommandKind.SkipUntilPass: { curLine = input.CurrentLine; bool foundNextLandMark = false; for (int i = curLine; i < lineCount; ++i) { string line = input.GetLine(i); input.CurrentLine++; if (line.TrimStart().StartsWith(cmd.String)) { AddControlLine(output, cmd); //*** //found land mark foundNextLandMark = true; //not add this //just skip break; } else { //skip } } if (!foundNextLandMark) { throw new NotSupportedException("next land mark not found"); } } break; case PatchCommandKind.SkipUntilAndAccept: { curLine = input.CurrentLine; bool foundNextLandMark = false; for (int i = curLine; i < lineCount; ++i) { string line = input.GetLine(i); input.CurrentLine++; if (line.TrimStart().StartsWith(cmd.String)) { //found land mark foundNextLandMark = true; //accept this line AddControlLine(output, cmd); //*** output.AddLine(line); break; } else { //skip } } if (!foundNextLandMark) { throw new NotSupportedException("next land mark not found"); } } break; default: throw new NotSupportedException(); } } }
/// <summary> /// create patch file from a patch file in disk /// </summary> /// <param name="filename"></param> /// <returns></returns> public static PatchFile BuildPatchFile(string filename) { //if (filename == "d:\\projects\\CefBridge\\cef3\\cefclient\\browser\\client_handler.cc") //{ //} //create patch command for specific filename PatchFile patchFile = new PatchFile(filename); SourceFile sourceFile = new SourceFile(filename, false); sourceFile.ReadAllLines(); int j = sourceFile.LineCount; PatchTask ptask = null; int i = 0; string line = sourceFile.GetLine(0); //first line is original filename string originalFilename; if (GetOriginalFilename(line, out originalFilename)) { //change origial file name for patch file patchFile.OriginalFileName = originalFilename; i++; //next line } for (; i < j; ++i) { line = sourceFile.GetLine(i).TrimStart(); if (line.StartsWith("//###_")) { //what is the comamnd int pos0 = line.IndexOf(' '); //first (must have if (pos0 < 0) { throw new NotSupportedException("pos 0"); } else { string additionalInfo; int taskId = GetTaskId(line, pos0 + 1, out additionalInfo); string cmdline = line.Substring(0, pos0); switch (cmdline) { case PatchCommand.START: //start new patch task //read next line for info { i++; string cmd_value = sourceFile.GetLine(i); //create new task ptask = new PatchTask(cmd_value, taskId); patchFile.AddTask(ptask); } break; case PatchCommand.APPPEND_START: //start collect append string //until find append_stop { var collectAppendStBuilder = new StringBuilder(); i++; string cmd_value = sourceFile.GetLine(i); line = cmd_value.TrimStart(); //eval do { if (line.StartsWith(PatchCommand.APPPEND_STOP)) { //stop here break; } else { if (line.StartsWith("//###_")) { //other command throw new NotSupportedException(); } else { //collect this line collectAppendStBuilder.AppendLine(line); //read next line i++; line = sourceFile.GetLine(i).TrimStart(); } } } while (true); //finish command ptask.Append(collectAppendStBuilder.ToString()); } break; case PatchCommand.APPPEND_STOP: throw new NotSupportedException(); case PatchCommand.FIND_NEXT_LANDMARK: { i++; string cmd_value = sourceFile.GetLine(i); if (taskId != ptask.TaskId) { throw new NotSupportedException(); } ptask.FindNext(cmd_value); } break; case PatchCommand.FOLLOW_BY: { i++; string cmd_value = sourceFile.GetLine(i); if (taskId != ptask.TaskId) { throw new NotSupportedException(); } ptask.FollowBy(cmd_value); } break; case PatchCommand.SKIP_UNTIL_AND_ACCEPT: { i++; string cmd_value = sourceFile.GetLine(i); if (taskId != ptask.TaskId) { throw new NotSupportedException(); } ptask.SkipUntilAndAccept(cmd_value); } break; case PatchCommand.SKIP_UNTIL_PASS: { //has 2 parameters if (additionalInfo == null) { throw new NotSupportedException(); } // ptask.SkipUntilPass(additionalInfo); } break; default: throw new NotSupportedException(); } } } } return((ptask != null && ptask.CommandCount > 0) ? patchFile : null); }