using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.IO; using System.Text.RegularExpressions; namespace difftool { class Program { static private string FirstLine(string s) { int i = s.IndexOf('\n'); return i > 0 ? s.Substring(0, i) : s; } static private List GetDiff(string[] s1, string[] s2) { List ret = new List(); int i2 = 0; while (i2 < s2.Length && (s2[i2] == "" || !s2[i2].StartsWith("mozilla/"))) i2++; for (int i1 = 0; i1 < s1.Length; ++i1) { if (s1[i1] == "" || !s1[i1].StartsWith("mozilla/")) continue; if (i2 >= s2.Length) { ret.Add(s1[i1]); continue; } if (FirstLine(s1[i1]) == FirstLine(s2[i2])) { ++i2; continue; } for (int i3 = i2 + 1; i3 < i2 + 300 && i3 < s2.Length; ++i3) { if (FirstLine(s1[i1]) == FirstLine(s2[i3])) { i2 = i3; break; } } if (FirstLine(s1[i1]) == FirstLine(s2[i2])) { ++i2; continue; } ret.Add(s1[i1]); } return ret; } static private string TextToHtml(string s) { return s.Replace("&", "&").Replace("<", "<").Replace(">", ">"); } static Boolean IsNameChar(char c) { return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_'; } // color theme: // http://www.eclipsecolorthemes.org/?view=theme&id=47 /* private const string backgroundColor = "1E1E1E"; private const string foregroundFont = ""; private const string keywordFont = ""; private const string numberFont = ""; private const string stringFont = ""; private const string singleLineCommentFont = ""; private const string multiLineCommentFont = ""; private const string lineNumberFont = ""; private const string graphBackgroundColor = "#303030"; private const string graphBorderColor = "#8DCBE2"; private const string graphTextColor = "#8DCBE2"; */ private const string backgroundColor = "white"; private const string foregroundFont = ""; private const string symbolFont = ""; private const string keywordFont = ""; private const string numberFont = ""; private const string stringFont = ""; private const string singleLineCommentFont = ""; private const string multiLineCommentFont = ""; private const string lineNumberFont = ""; private const string graphBackgroundColor = "#e0e0e0"; private const string graphBorderColor = "black"; private const string graphTextColor = "black"; static private void writeSourceFile(string path, string w, string filename) { string errorLoc; string errorMessage; if (w[0] == '[') { errorLoc = w.Substring(1, w.IndexOf(']') - 1); int i1 = w.IndexOf(')') + 1; errorMessage = w.Substring(i1); } else { errorLoc = w.Substring(0, w.IndexOf(':', w.IndexOf(':') + 1)); int i1 = w.IndexOf(": ", w.IndexOf(": ") + 1) + 1; int i2 = w.LastIndexOf('[') - 1; errorMessage = w.Substring(i1, i2 - i1).Trim(); } string f = errorLoc.Substring(0, errorLoc.LastIndexOf(':')); int errorLine = Int32.Parse(errorLoc.Substring(1 + errorLoc.LastIndexOf(':'))); string symbolName = ""; if (errorMessage.IndexOf(": ") > 5) { string end = errorMessage.Substring(errorMessage.LastIndexOf(": ")); // get symbol name Regex regex = new Regex(": '?[a-zA-Z_][a-zA-Z0-9_]*'?\\.?"); if (regex.IsMatch(end)) symbolName = end.Trim(':', ' ', '\'', '.'); } string[] lines = System.IO.File.ReadAllLines(path + f); string[] keywords = { "void", "bool", "char", "short", "int", "long", "double", "float", "class", "struct", "union", "enum", "namespace", "friend", "using", "for", "if", "while", "switch", "case", "default", "return", "goto", "break", "continue", "throw", "unsigned", "signed", "private", "protected", "public", "static", "const", "template", "typename", "auto", "virtual", "true", "false", "this" }; System.IO.StreamWriter file = new System.IO.StreamWriter(path + filename); file.WriteLine(""); file.WriteLine(""); file.WriteLine("" + TextToHtml(w) + ""); file.WriteLine(""); file.WriteLine(""); file.WriteLine("
" + foregroundFont + TextToHtml(w) + "\n");
            int linenr = 0;
            bool multiline = false;
            foreach (string line in lines)
            {
                ++linenr;
                file.Write(lineNumberFont + (linenr.ToString() + "        ").Substring(0, 8) + "");

                for (int i = 0; i < line.Length;)
                {
                    if (line[i] == ' ')
                    {
                        file.Write(line[i]);
                        i++;
                    }
                    else if (multiline)
                    {
                        string currentToken = "";
                        while (i < line.Length && multiline)
                        {
                            currentToken += line[i];
                            i++;
                            if (currentToken.EndsWith("*/"))
                                multiline = false;
                        }
                        file.Write(multiLineCommentFont + TextToHtml(currentToken) + "");
                    }
                    else if (IsNameChar(line[i]))
                    {
                        string currentToken = "";
                        while (i < line.Length && IsNameChar(line[i]))
                        {
                            currentToken += line[i];
                            i++;
                        }
                        if (currentToken == symbolName)
                            file.Write(symbolFont + currentToken + "");
                        else if (keywords.Contains(currentToken))
                            file.Write(keywordFont + currentToken + "");
                        else if (currentToken[0] >= '0' && currentToken[0] <= '9')
                            file.Write(numberFont + currentToken + "");
                        else
                            file.Write(currentToken);
                    }
                    else if (line[i] == '\"' || line[i] == '\'')
                    {
                        string currentToken = "";
                        while (i < line.Length)
                        {
                            currentToken += line[i];
                            i++;
                            if (currentToken.Length > 1 && currentToken[0] == line[i - 1])
                                break;
                        }
                        file.Write(stringFont + TextToHtml(currentToken) + "");
                    }
                    else if (line[i] == '/' && i + 1 < line.Length && line[i + 1] == '/')
                    {
                        file.Write(singleLineCommentFont + TextToHtml(line.Substring(i)) + "");
                        i = line.Length;
                    }
                    else if (line[i] == '/' && i + 1 < line.Length && line[i + 1] == '*')
                    {
                        multiline = true;
                        string currentToken = "/*";
                        i += 2;
                        while (i < line.Length && multiline)
                        {
                            currentToken += line[i];
                            i++;
                            if (currentToken.Length > 3 && currentToken.EndsWith("*/"))
                                multiline = false;
                        }
                        file.Write(multiLineCommentFont + TextToHtml(currentToken) + "");
                    }
                    else
                    {
                        file.Write(TextToHtml(line.Substring(i, 1)));
                        i++;
                    }
                }
                file.Write('\n');

                if (errorLine == linenr)
                    file.WriteLine("
" + TextToHtml(errorMessage) + "
"); } file.Write("
"); file.Close(); } static private void combineWarnings(string[] lines) { for (int i = 0; i < lines.Length; ++i) { if (lines[i].IndexOf(": note:") > 0 || !lines[i].StartsWith("mozilla/")) lines[i] = ""; continue; int i2 = i + 1; while (i2 < lines.Length && lines[i2].IndexOf(": note:") > 0) { lines[i] = lines[i] + '\n' + lines[i2]; lines[i2] = ""; i2++; } } } static void Main(string[] args) { string path; if (Directory.Exists("/home/danielm/shared/testing")) path = "/home/danielm/shared/testing/"; else if (Directory.Exists("/home/danielm/testing")) path = "/home/danielm/testing/"; else if (Directory.Exists(@"c:\Users\danielm.evidente\testing")) path = @"c:\Users\danielm.evidente\testing\"; else { Console.WriteLine("Directory testing not found"); return; } string[] old = System.IO.File.ReadAllLines(path + "1.82.txt"); string[] head = System.IO.File.ReadAllLines(path + "head.txt"); combineWarnings(old); combineWarnings(head); Array.Sort(old, StringComparer.InvariantCulture); Array.Sort(head, StringComparer.InvariantCulture); List removed = GetDiff(old, head); List added = GetDiff(head, old); int fileIndex = 1; using (System.IO.StreamWriter file = new System.IO.StreamWriter(path + "html/main.html")) { file.WriteLine(""); file.WriteLine(""); file.WriteLine("Comparison 1.82 / Head"); file.WriteLine(""); file.WriteLine(""); file.WriteLine(foregroundFont); file.WriteLine("

Comparison 1.82 / Head

"); file.WriteLine("

Package: {0}

", @"ftp://ftp.se.debian.org/debian/pool/main/f/firefox/firefox_59.0~b4.orig.tar.bz2"); file.WriteLine("

+ Added warnings {0}

", added.Count); file.WriteLine("

- Removed warnings {0}

", removed.Count); file.WriteLine("", 60 + Math.Max(added.Count, removed.Count) + 10, 40); file.WriteLine(" "); file.WriteLine(" Added"); file.WriteLine(" Removed"); file.WriteLine(" ", added.Count); file.WriteLine(" ", removed.Count); file.WriteLine(""); string[] title = { "Added warnings", "Removed warnings" }; List[] warnings = { added, removed }; for (int i = 0; i < 2; i++) { file.WriteLine("

" + title[i] + "

"); file.WriteLine("
");
                    foreach (string w in warnings[i])
                    {
                        string filename = "code" + fileIndex.ToString() + ".html";
                        fileIndex++;
                        writeSourceFile(path, w, "html/" + filename);
                        file.WriteLine("{1}", filename, TextToHtml(w));
                    }
                    file.WriteLine("
"); } file.WriteLine(""); file.WriteLine(""); } } } }