Skip to content

Instantly share code, notes, and snippets.

@recuraki
Created October 26, 2016 16:09
Show Gist options
  • Save recuraki/490a76338417daaaaa12f09951742d7c to your computer and use it in GitHub Desktop.
Save recuraki/490a76338417daaaaa12f09951742d7c to your computer and use it in GitHub Desktop.
CiscoDiff
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