public HycalperConsole(string filename, string targetDir) { try { m_targetPath = targetDir; int curPosition = 0; bool write2same_file = false; string input = System.IO.File.ReadAllText(filename); m_linesGlobal = countLines(input); if (input.Length > 0) { // read xml types from input file int lenXML = 0; m_pattern = readTypesXML(ref input, out lenXML, ref m_xmlDoc, false); if (lenXML == 0) { m_message = "There is nothing to hycalpe here!"; m_error = 3; return; } if (m_pattern == null) throw new Exception("Invalid XML Types definition."); // extract outfile XmlNode outFileNameNode = m_xmlDoc.GetElementsByTagName ( "outfile" ).Item ( 0 ); if (outFileNameNode != null && outFileNameNode.InnerText != null && outFileNameNode.InnerText.Length > 0) { m_saveFilename = Path.Combine(Path.GetDirectoryName(filename) , outFileNameNode.InnerText); if (m_saveFilename == null || m_saveFilename.Length == 0) throw new Exception("Unable to find / extract outfile specification."); } else { // save to self m_saveFilename = filename; write2same_file = true; } // skip if uptodate if (skip_uptodate && !write2same_file) { DateTime lastAccessOutfile = File.GetLastWriteTime ( m_saveFilename ); DateTime lastAccessSource = File.GetLastWriteTime ( filename ); if (lastAccessOutfile > lastAccessSource) { // skip m_message = "...uptodate -> skipped."; m_error = 2; return; } } // extract + process loops curPosition = input.IndexOf(LOOPSTART); int appendIdx = curPosition; while (curPosition >= 0) { int [] excludePattern; Types localPattern; string loopSequence = extractLoop(input, ref curPosition, out localPattern, out excludePattern); if (loopSequence != null) { if (localPattern == null) localPattern = m_pattern; System.Array.Sort(excludePattern); appendIdx = beginOfLine(input, curPosition); // if old marks -> remove content between them if (write2same_file) { int startIdx = input.Substring(0, endOfLine(input, appendIdx)).IndexOf(AUTOGENERATEDSTART, appendIdx); if (startIdx >= 0) { int endIdx = nextNewLine(input, input.IndexOf(AUTOGENERATEDEND, startIdx)); if (endIdx > startIdx) { input = input.Remove(appendIdx, endIdx - appendIdx); } } } // create new region marks if (parenthesize || write2same_file) { input = input.Insert(appendIdx, Environment.NewLine + AUTOGENERATEDEND + Environment.NewLine); } int curExcludingIdx = 0; for (int i = 0; i < localPattern.CountPattern; i++) { // replace only pattern which are not excluded if (curExcludingIdx >= excludePattern.Length || excludePattern[curExcludingIdx] != i) { int tagsReplaced = 0; string insertString = replaceAllKeys(loopSequence, localPattern, i, ref tagsReplaced); insertString = removeCommentStubs(insertString, "/*!HC", "*/"); // insert only, if something was replaced if (tagsReplaced > 0) { input = input.Insert(appendIdx, insertString); curPosition += insertString.Length; } } else { curExcludingIdx++; } } if (parenthesize || write2same_file) { string endMark = AUTOGENERATEDSTART + Environment.NewLine; if (write2same_file) endMark = endMark + "// DO NOT EDIT INSIDE THIS REGION !! CHANGES WILL BE LOST !! " + Environment.NewLine; input = input.Insert(appendIdx, endMark); curPosition += endMark.Length; } m_loops++; } else { throw new Exception("Error extracting loop sequence: " + m_message); } curPosition = input.IndexOf(LOOPSTART, curPosition + 1); } // find and process enums curPosition = input.IndexOf(ENUMPATTERN, 0); while (curPosition >= 0) { int startIdx = input.IndexOfAny(WHITESPACE,curPosition); int startKeyIdx = curPosition + ENUMPATTERN.Length; int endKeyIdx = input.IndexOfAny(new char[11] { ':', ' ', ',', '*', '/', '(', ')', '}', '{', '\r', '\n' }, startKeyIdx); appendIdx = endOfWord(input,endKeyIdx); if (endKeyIdx > startKeyIdx) { string key = input.Substring(startKeyIdx, endKeyIdx - startKeyIdx).Trim(); string insertString = enumAllKeyPatterns(key); endKeyIdx = input.IndexOf(ENUMPATTERNEND, endKeyIdx); if (endKeyIdx < 0 ) throw new Exception("Missing enum end tag!"); endKeyIdx = beginOfWord(input,endKeyIdx); input = input.Remove(appendIdx, endKeyIdx - appendIdx); input = input.Insert(appendIdx, " " + insertString + " "); curPosition += insertString.Length; m_enums++; } else { throw new Exception("Missing class spec in enum."); } curPosition = input.IndexOf(ENUMPATTERN, curPosition + 1); } // Comment if (comment && input.IndexOf("namespace") > 2) { string commentString; if (write2same_file) { commentString = "//////////////////////////////////////////////////////////////////" + Environment.NewLine + "// //" + Environment.NewLine + "// This is an auto - manipulated source file. //" + Environment.NewLine + "// Edits inside regions of HYCALPER AUTO GENERATED CODE //" + Environment.NewLine + "// will be lost and overwritten on the next build! //" + Environment.NewLine + "// //" + Environment.NewLine + "//////////////////////////////////////////////////////////////////" + Environment.NewLine; } else { commentString = "//////////////////////////////////////////////////////////////////" + Environment.NewLine + "// This is an auto - generated source file. //" + Environment.NewLine + "// Do not manually edit this file! Any changes made will be //" + Environment.NewLine + "// lost on the next build! Edit the corresponding source file //" + Environment.NewLine + "// (per default located in the template/ folder) instead! //" + Environment.NewLine + "// //" + Environment.NewLine + "//////////////////////////////////////////////////////////////////" + Environment.NewLine; } XmlNode commentNode = m_xmlDoc.GetElementsByTagName("comment")[0]; if (commentNode != null && commentNode.InnerText != null) { commentString += Environment.NewLine + "///////////////////// UserComment: ///////////////////////////////" + Environment.NewLine + "/*" + commentNode.InnerText + "*/"; } if (input.IndexOf(commentString) < 0) { input = input.Insert(0,commentString); } } // write to file if (m_saveFilename != null) { System.IO.File.WriteAllText(m_saveFilename, input); } m_error = 0; return; } } catch (Exception e) { m_message = e.Message; m_error = 1; return; } }
/// <summary> /// all occurences of any type of locPattern in 'input' will be replaced by their /// corresponding replace pattern /// </summary> /// <param name="input">loop sequence</param> /// <param name="destIdx">index into destination string</param> /// <returns>loop sequence having all occourences of keys in my pattern /// replaced with corresponding destination string out of my patterns (index idx). /// </returns> private string replaceAllKeys(String input,Types locPattern, int destIdx, ref int tagsReplaced) { string ret = ""; tagsReplaced = 0; if (locPattern.CountKey > 0) { ret = input; foreach (string key in locPattern.Pattern.Keys) { switch (locPattern.Location(key)) { case "after": // replace first string after pattern with destination string[] founds = ret.Split(new string[1] { key }, StringSplitOptions.None); StringBuilder sb = new StringBuilder(founds[0]); for (int i = 1; i < founds.Length; i++) { if (founds[i - 1].LastIndexOf("ENUM:") == founds[i - 1].Length - "ENUM:".Length && founds[i - 1].Length >= "ENUM:".Length) { sb.Append(key + founds[i]); continue; } int startIdx = beginOfPattern(founds[i],0); // new: allow without whitespace! was: nextWord(founds[i], 0); //startIdx = nextWord( int endIdx = endOfPattern(founds[i],startIdx,locPattern.EndMark[key]); // endOfWord(founds[i],startIdx); if (endIdx > startIdx) { // do the actual replace ... founds[i] = founds[i].Remove(startIdx, endIdx - startIdx); founds[i] = founds[i].Insert(startIdx, locPattern[key,destIdx]); sb.Append(founds[i]); tagsReplaced++; } else { sb.Append(founds[i]); } } ret = sb.ToString(); break; case "here": // replace all key strings directly by destination ret = ret.Replace(key, locPattern[key, destIdx]); tagsReplaced++; break; case "nextline": // replace next line completely int curpos = ret.LastIndexOf(key); while (curpos >= 0) { // check if hycalper tag int eL = endOfLine(ret,curpos); int bL = beginOfLine(ret,curpos); // found int startIdx; int endIdx; if (keep_tags) { startIdx = nextNewLine(ret, eL); endIdx = nextNewLine(ret, startIdx); } else { startIdx = bL; endIdx = nextNewLine(ret, nextNewLine(ret, startIdx)); } string ind = indent(ret,curpos); ret = ret.Remove(startIdx, endIdx - startIdx); ret = ret.Insert(startIdx,ind + locPattern[key, destIdx] + Environment.NewLine); curpos = ret.Substring(0, bL).LastIndexOf(key); tagsReplaced++; } break; case "endregion": // replace lines (after -> 'keep_tags == true') the line containing the key until line containing '#endregion HYCALPER' was found curpos = ret.IndexOf(key); while (curpos >= 0) { int startIdx; int endIdx; string indent = new string (' ',firstNonWhitespace(ret,curpos) - beginOfLine(ret,curpos)); if (keep_tags) { startIdx = nextNewLine(ret,curpos); endIdx = ret.IndexOf("#endregion HYCALPER", startIdx); } else { startIdx = beginOfLine(ret, curpos); endIdx = endOfLine(ret,ret.IndexOf("#endregion HYCALPER",startIdx)); } if (startIdx > 0 && endIdx > startIdx) { ret = ret.Remove(startIdx, endIdx - startIdx); string insert = indent + locPattern[key, destIdx]; ret = ret.Insert(startIdx, insert); curpos = startIdx + insert.Length; tagsReplaced++; } curpos = ret.IndexOf(key,curpos); } break; case "comment": // replace text between the FIRST occurence of xml-comment tags <bla> and </bla>. 'bla': name of pattern string startTag = "<" + key + ">", endTag; if (!key.StartsWith("param")) endTag = "</" + key + ">"; else endTag = "</param>"; curpos = ret.IndexOf(startTag); if (curpos >= 0) { int startIdx = curpos + startTag.Length; int endIdx = ret.IndexOf(endTag,startIdx); if (endIdx <= startIdx) throw new Exception("missing closing comment tag: " + endTag); string indent = new string (' ',firstNonWhitespace(ret,startIdx) - beginOfLine(ret,startIdx)); if (startIdx > 0 && endIdx > startIdx) { ret = ret.Remove(startIdx, endIdx - startIdx); string insert = locPattern[key, destIdx].Replace(Environment.NewLine, Environment.NewLine + indent + "/// "); ret = ret.Insert(startIdx, insert); tagsReplaced++; } } break; } } } return ret; }
public Hycalper(Types pattern) { m_pattern = pattern; }
private string extractLoop(string input, ref int curloopstart,out Types localPattern, out int[] excludePattern) { string ret = null; excludePattern = new int [0]; localPattern = null; try { int startIdx = input.IndexOf(LOOPSTART, curloopstart) + LOOPSTART.Length; startIdx = endOfWord(input,startIdx); int lineEnd = endOfLine(input,startIdx); string [] parameter = input.Substring ( startIdx, lineEnd - startIdx ).Trim ().Split(' '); // handle parameter bool readingFromFile = false; string fileName = ""; string loopName = ""; foreach (string param in parameter) { if (param.IndexOf ( '@' ) > 0) { string [] tmpLine = param.Trim().Split ( '@' ); if (tmpLine.Length == 2) { readingFromFile = true; loopName = tmpLine[0].Trim(); fileName = tmpLine[1].Trim(); } else Console.Out.WriteLine("INVALID FILE REFERENCE IN LOOP DEFINITION at " + curloopstart); } if (param.Contains ( EXCLUDEPATTERN )) { string [] tmpLine = param.Trim ().Split ('=', ' ', ',', ':', ';' ); if (tmpLine.Length > 0) { if (tmpLine[0].Trim().CompareTo(EXCLUDEPATTERN) != 0) { Console.Out.WriteLine("ERROR PARSING EXCLUDE PATTERN. Exp: " + EXCLUDEPATTERN + "=1,5,7,14"); excludePattern = new int[0]; return ""; } excludePattern = new int [tmpLine.Length-1]; try { for (int i = 1; i < tmpLine.Length; i++) { excludePattern [i-1] = int.Parse ( tmpLine [i].Trim() ); } } catch (Exception e) { Console.Out.WriteLine ( "ERROR PARSING EXCLUDE PATTERN: " + e.Message + "at " + curloopstart ); excludePattern = new int [0]; } } } } int endIdx = 0; startIdx = nextNewLine(input, startIdx); endIdx = beginOfLine(input, input.IndexOf(LOOPEND, startIdx)); if (endIdx > 0 && endIdx > startIdx) { ret = input.Substring ( startIdx, endIdx - startIdx ); } // read local pattern definition (if any) XmlDocument locXML = null; int lengthXML = 0; localPattern = readTypesXML(ref ret, out lengthXML, ref locXML, true); if (readingFromFile) { // read loop from file ret = extractLoopFromFile ( fileName, loopName ); } // set cursor after loop marks curloopstart = nextNewLine ( input, input.IndexOf ( LOOPEND, curloopstart ) ); return ret; } catch (Exception e) { m_message = e.Message; return null; } }
public Hycalper(Types pattern) { m_pattern = pattern; }