~ubuntu-branches/ubuntu/maverick/monodevelop/maverick

« back to all changes in this revision

Viewing changes to src/addins/VersionControl/MonoDevelop.VersionControl/MonoDevelop.VersionControl.Views/DiffParser.cs

  • Committer: Bazaar Package Importer
  • Author(s): Jo Shields
  • Date: 2010-07-05 13:00:05 UTC
  • mfrom: (1.2.8 upstream) (1.3.9 experimental)
  • Revision ID: james.westby@ubuntu.com-20100705130005-d6hp4k5gcn1xkj8c
Tags: 2.4+dfsg-1ubuntu1
* debian/patches/remove_support_for_moonlight.patch,
  debian/patches/dont_add_moonlight_to_core_addins.patch,
  debian/control:
  + Enable support for Moonlight
* debian/rules:
  + Ensure Moonlight addin isn't shipped in main MonoDevelop package by
    mistake

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// 
 
2
// DiffParser.cs
 
3
//  
 
4
// Author:
 
5
//       Levi Bard <taktaktaktaktaktaktaktaktaktak@gmail.com>
 
6
// 
 
7
// Copyright (c) 2010 Levi Bard
 
8
// 
 
9
// Permission is hereby granted, free of charge, to any person obtaining a copy
 
10
// of this software and associated documentation files (the "Software"), to deal
 
11
// in the Software without restriction, including without limitation the rights
 
12
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 
13
// copies of the Software, and to permit persons to whom the Software is
 
14
// furnished to do so, subject to the following conditions:
 
15
// 
 
16
// The above copyright notice and this permission notice shall be included in
 
17
// all copies or substantial portions of the Software.
 
18
// 
 
19
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
20
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
21
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 
22
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 
23
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 
24
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 
25
// THE SOFTWARE.
 
26
 
 
27
using System;
 
28
using System.IO;
 
29
using System.Text.RegularExpressions;
 
30
 
 
31
using MonoDevelop.Core;
 
32
using MonoDevelop.Projects.Dom;
 
33
using MonoDevelop.Projects.Dom.Parser;
 
34
 
 
35
namespace MonoDevelop.VersionControl.Views
 
36
{
 
37
        /// <summary>
 
38
        /// Parser for unified diffs
 
39
        /// </summary>
 
40
        public class DiffParser: AbstractParser
 
41
        {
 
42
                // Match the original file and time/revstamp line, capturing the filepath and the stamp
 
43
                static Regex fileHeaderExpression = new Regex (@"^---\s+(?<filepath>[^\t]+)\t(?<stamp>.*)$", RegexOptions.Compiled);
 
44
                
 
45
                // Match a chunk header line
 
46
                static Regex chunkExpression = new Regex (@"^@@\s+(?<chunk>-\d+,\d+\s+\+\d+,\d+)\s+@@", RegexOptions.Compiled);
 
47
                
 
48
                // Capture the file's EOL string
 
49
                static Regex eolExpression = new Regex (@"(?<eol>\r\n|\n|\r)", RegexOptions.Compiled);
 
50
                
 
51
                public DiffParser (): base("Diff", "text/x-diff")
 
52
                {
 
53
                }
 
54
                
 
55
                #region AbstractParser overrides
 
56
                
 
57
                public override bool CanParse (string fileName)
 
58
                {
 
59
                        if (!string.IsNullOrEmpty (fileName)) {
 
60
                                string extension = Path.GetExtension (fileName);
 
61
                                return (".diff".Equals (extension, StringComparison.OrdinalIgnoreCase) ||
 
62
                                        ".patch".Equals (extension, StringComparison.OrdinalIgnoreCase));
 
63
                        }
 
64
                        
 
65
                        return false;
 
66
                }
 
67
                
 
68
                public override bool CanParseMimeType (string mimeType)
 
69
                {
 
70
                        return (!string.IsNullOrEmpty (mimeType) &&
 
71
                                "text/x-diff".Equals (mimeType.Trim (), StringComparison.Ordinal));
 
72
                }
 
73
                
 
74
                public override bool CanParseProjectType (string projectType)
 
75
                {
 
76
                        return true;
 
77
                }
 
78
                
 
79
                public override ParsedDocument Parse (ProjectDom dom, string fileName, string content)
 
80
                {
 
81
                        ParsedDocument doc = new ParsedDocument (fileName);
 
82
                        if(null == doc.CompilationUnit)
 
83
                                doc.CompilationUnit = new CompilationUnit (fileName);
 
84
                        CompilationUnit cu = (CompilationUnit)doc.CompilationUnit;
 
85
                        DomType currentFile = null;
 
86
                        DomProperty currentRegion = null;
 
87
                        
 
88
                        string eol = Environment.NewLine;
 
89
                        Match eolMatch = eolExpression.Match (content);
 
90
                        if (eolMatch != null && eolMatch.Success)
 
91
                                eol = eolMatch.Groups["eol"].Value;
 
92
                        
 
93
                        string[] lines = content.Split (new string[]{eol}, StringSplitOptions.None);
 
94
                        int linenum = 1;
 
95
                        Match lineMatch;
 
96
                        foreach (string line in lines)
 
97
                        {
 
98
                                lineMatch = fileHeaderExpression.Match (line.Trim());
 
99
                                if (lineMatch != null && lineMatch.Success) {
 
100
                                        if (currentFile != null) // Close out previous file region
 
101
                                                currentFile.BodyRegion = new DomRegion (currentFile.BodyRegion.Start.Line,
 
102
                                                                                        currentFile.BodyRegion.Start.Column,
 
103
                                                                                        linenum-1, int.MaxValue);
 
104
                                        if (currentRegion != null) // Close out previous chunk region
 
105
                                                currentRegion.BodyRegion = new DomRegion (currentRegion.BodyRegion.Start.Line,
 
106
                                                                                          currentRegion.BodyRegion.Start.Column,
 
107
                                                                                          linenum-1, int.MaxValue);
 
108
                                        
 
109
                                        // Create new file region
 
110
                                        currentFile = new DomType (cu, ClassType.Unknown, Modifiers.None, 
 
111
                                                                   lastToken (lineMatch.Groups["filepath"].Value),
 
112
                                                                   new DomLocation (linenum, 1), 
 
113
                                                                   string.Empty,
 
114
                                                                   new DomRegion (linenum, line.Length+1, linenum, int.MaxValue));
 
115
                                        cu.Add (currentFile);
 
116
                                } else {
 
117
                                        lineMatch = chunkExpression.Match (line);
 
118
                                        if (lineMatch != null && lineMatch.Success) {
 
119
                                                if (currentRegion != null) // Close out previous chunk region
 
120
                                                        currentRegion.BodyRegion = new DomRegion (currentRegion.BodyRegion.Start.Line,
 
121
                                                                                                  currentRegion.BodyRegion.Start.Column,
 
122
                                                                                                  linenum-1, int.MaxValue);
 
123
                                                
 
124
                                                // Create new chunk region
 
125
                                                currentRegion = new DomProperty (lineMatch.Groups["chunk"].Value, Modifiers.None, 
 
126
                                                                                 new DomLocation (linenum, 1), 
 
127
                                                                                 new DomRegion (linenum, line.Length+1, linenum, int.MaxValue), null);
 
128
                                                currentFile.Add (currentRegion);
 
129
                                        }
 
130
                                }
 
131
                                ++linenum;
 
132
                        }
 
133
                        
 
134
                        // Close out trailing regions
 
135
                        if (currentFile != null)
 
136
                                currentFile.BodyRegion = new DomRegion (currentFile.BodyRegion.Start.Line,
 
137
                                                                        currentFile.BodyRegion.Start.Column, 
 
138
                                                                        Math.Max (1, linenum-2), int.MaxValue);
 
139
                        if (currentRegion != null)
 
140
                                currentRegion.BodyRegion = new DomRegion (currentRegion.BodyRegion.Start.Line,
 
141
                                                                          currentRegion.BodyRegion.Start.Column, 
 
142
                                                                          Math.Max (1, linenum-2), int.MaxValue);
 
143
                        
 
144
                        return doc;
 
145
                }
 
146
                
 
147
                #endregion
 
148
                
 
149
                // Return the last token from a filepath 
 
150
                // (delimiter may not match Path.DirectorySeparatorChar)
 
151
                static string lastToken (string filepath)
 
152
                {
 
153
                        if (!string.IsNullOrEmpty (filepath)) {
 
154
                                string[] tokens = filepath.Split (new char[]{'\\','/'}, StringSplitOptions.RemoveEmptyEntries);
 
155
                                return tokens[tokens.Length-1];
 
156
                        }
 
157
                        
 
158
                        return string.Empty;
 
159
                }
 
160
        }
 
161
}
 
162