Created
October 26, 2016 16:09
-
-
Save recuraki/490a76338417daaaaa12f09951742d7c to your computer and use it in GitHub Desktop.
CiscoDiff
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
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
using System.Threading.Tasks; | |
using System.Text.RegularExpressions; | |
using System.Diagnostics; | |
namespace CiscoDiff | |
{ | |
public class ConfigTreeObject | |
{ | |
public Dictionary<string, ConfigTreeObject> ConfigTree { get; set; } = | |
new Dictionary<string, ConfigTreeObject>(); | |
public ConfigTreeObject() | |
{ | |
} | |
public ConfigTreeObject(string key) | |
{ | |
ConfigTree[key] = new ConfigTreeObject(); | |
} | |
public void setvalue(string key, ConfigTreeObject value) | |
{ | |
ConfigTree[key] = value; | |
} | |
public void setvaluenull(string key) | |
{ | |
ConfigTree[key] = new ConfigTreeObject(); | |
} | |
public ConfigTreeObject getvalue(string key) | |
{ | |
if (ConfigTree.ContainsKey(key)) | |
return (ConfigTree[key]); | |
else | |
return (new ConfigTreeObject()); | |
} | |
public IEnumerable<string> keys() | |
{ | |
return ConfigTree.Keys; | |
} | |
public Boolean ContainsKey(string key) | |
{ | |
return ConfigTree.ContainsKey(key); | |
} | |
public void merge(ConfigTreeObject source) | |
{ | |
foreach (string key in source.keys().ToArray()) | |
this.setvalue(key, source.getvalue(key)); | |
} | |
public void dump(int indent = 0) | |
{ | |
foreach (string key in ConfigTree.Keys) | |
{ | |
Debug.WriteLine(string.Concat(Enumerable.Repeat(" ", indent)) + key + "["); | |
ConfigTree[key].dump(indent + 1); | |
Debug.WriteLine(string.Concat(Enumerable.Repeat(" ", indent)) + "]"); | |
} | |
} | |
} | |
class CiscoDiff | |
{ | |
private ConfigTreeObject beforeConfig; | |
private ConfigTreeObject afterConfig; | |
private ConfigTreeObject list2dict(List<List<string>> ConfigList) | |
{ | |
ConfigTreeObject Config = new ConfigTreeObject(); | |
foreach(List<string> Elem in ConfigList) | |
{ | |
ConfigTreeObject res = list2dictRoutine(Config, Elem); | |
Config.merge(res); | |
} | |
Config.dump(); | |
return Config; | |
} | |
private ConfigTreeObject list2dictRoutine(ConfigTreeObject Config, List<string> Line) | |
{ | |
if (Line.Count == 0) | |
return new ConfigTreeObject(); | |
string Elem = Line[0]; | |
List<string> ChildElems = Line.Skip(1).ToList(); | |
if(Config.ContainsKey(Elem) == false) | |
{ | |
Config.setvaluenull(Elem); | |
} | |
else | |
{ | |
ConfigTreeObject r = list2dictRoutine(Config.getvalue(Elem), ChildElems); | |
Config.setvalue(Elem, r); | |
} | |
return (Config); | |
} | |
private string lineList2Strs(List<string> liLevel) | |
{ | |
string s = ""; | |
for (int i = 0; i < liLevel.Count(); i++) | |
{ | |
s += (string.Concat(Enumerable.Repeat(" ", i)) + liLevel[i] + "\r\n"); | |
} | |
return s; | |
} | |
public string diff_remove(ConfigTreeObject beforeTree, ConfigTreeObject afterTree, List<string> liLevel) | |
{ | |
string res = ""; | |
foreach(string key in beforeTree.keys()) | |
{ | |
if(afterTree.ContainsKey(key) == false) | |
{ | |
res += lineList2Strs(liLevel); | |
res += string.Concat(Enumerable.Repeat(" ", liLevel.Count())); | |
res += "no " + key + "\r\n"; | |
res += "end" + "\r\n"; | |
} | |
else | |
{ | |
var NextLevel = new List<string>(liLevel); | |
NextLevel.Add(key); | |
res += diff_remove(beforeTree.getvalue(key), afterTree.getvalue(key), NextLevel); | |
} | |
} | |
return res; | |
} | |
public string diff_add(ConfigTreeObject beforeTree, ConfigTreeObject afterTree, List<string> liLevel) | |
{ | |
string res = ""; | |
foreach (string key in afterTree.keys()) | |
{ | |
if (beforeTree.ContainsKey(key) == false) | |
{ | |
res += lineList2Strs(liLevel); | |
res += string.Concat(Enumerable.Repeat(" ", liLevel.Count())); | |
res += key + "\r\n"; | |
res += "end" + "\r\n"; | |
liLevel.Add(key); | |
var NextLevel = new List<string>(liLevel); | |
NextLevel.Add(key); | |
res += diff_add(new ConfigTreeObject(), afterTree.getvalue(key), NextLevel); | |
} | |
else | |
{ | |
var NextLevel = new List<string>(liLevel); | |
NextLevel.Add(key); | |
res += diff_add(beforeTree.getvalue(key), afterTree.getvalue(key), NextLevel); | |
} | |
} | |
return res; | |
} | |
public string diff() | |
{ | |
string res = ""; | |
res += diff_remove(beforeConfig, afterConfig, new List<string>()); | |
res += diff_add(beforeConfig, afterConfig, new List<string>()); | |
return res; | |
} | |
public void updateBefore(List<List<string>> ConfigList) | |
{ | |
beforeConfig = list2dict(ConfigList); | |
} | |
public void updateAfter(List<List<string>> ConfigList) | |
{ | |
afterConfig = list2dict(ConfigList); | |
} | |
/// <summary> | |
/// 該当行がコメントかどうかを判定します | |
/// </summary> | |
/// <param name="line"></param> | |
/// <returns></returns> | |
public Boolean isComment(string line) | |
{ | |
if (line.Trim() == "!") | |
return true; | |
else | |
return false; | |
} | |
public int CountPrefixChars(char target, string line) | |
{ | |
int c = 0; | |
if (line == "") | |
return (0); | |
if(line[0] == target) | |
return (1 + CountPrefixChars(target, line.Substring(1))); | |
return (0); | |
} | |
public List<List<string>> ParseText(string Text) | |
{ | |
var Current = new List<string>(); | |
var Config = new List<List<string>>(); | |
string curLine; | |
string[] lines; | |
lines = Regex.Split(Text, "\n"); | |
foreach(string line in lines) | |
{ | |
curLine = line.TrimStart().TrimEnd('\r'); | |
Debug.WriteLine(curLine); | |
if (isComment(curLine)) | |
continue; | |
if (curLine == "") | |
continue; | |
Current = ParseConf(line, Current); | |
Config.Add(Current); | |
} | |
return (Config); | |
} | |
public List<String> ParseConf(string line) | |
{ | |
return (ParseConf(line, new List<string>())); | |
} | |
public List<String> ParseConf(string line, List<string> Prev) | |
{ | |
int depthCur = CountPrefixChars(' ', line); | |
Debug.WriteLine(depthCur.ToString()); | |
int depthPrev = Prev.Count(); | |
Debug.WriteLine(depthPrev.ToString()); | |
List<string> result = Prev.Take(depthCur).ToList(); | |
line = line.Trim(); | |
result.Add(line); | |
return (result); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment