OSDN Git Service

Fix a crash problem when the Diff algorithm is set to something other than default...
[winmerge-jp/winmerge-jp.git] / Src / CompareOptions.cpp
1 /** 
2  * @file  CompareOptions.cpp
3  *
4  * @brief Compare options implementation.
5  */
6
7 #include "pch.h"
8 #include "CompareOptions.h"
9 #include "diff.h"
10
11 // Global defined in diffutils code
12 extern DECL_TLS int recursive;
13
14 /**
15  * @brief Default constructor.
16  */
17 CompareOptions::CompareOptions()
18 : m_ignoreWhitespace(WHITESPACE_COMPARE_ALL)
19 , m_bIgnoreBlankLines(false)
20 , m_bIgnoreCase(false)
21 , m_bIgnoreEOLDifference(false)
22 , m_bIgnoreNumbers(false)
23 {
24 }
25
26 /**
27  * @brief Sets options from DIFFOPTIONS structure.
28  * @param [in] options Diffutils options.
29  */
30 void CompareOptions::SetFromDiffOptions(const DIFFOPTIONS &options)
31 {
32         switch (options.nIgnoreWhitespace)
33         {
34         case 0:
35                 m_ignoreWhitespace = WHITESPACE_COMPARE_ALL;
36                 break;
37         case 1:
38                 m_ignoreWhitespace = WHITESPACE_IGNORE_CHANGE;
39                 break;
40         case 2:
41                 m_ignoreWhitespace = WHITESPACE_IGNORE_ALL;
42                 break;
43         default:
44                 throw "Unknown whitespace ignore value!";
45                 break;
46         }
47         m_bIgnoreBlankLines = options.bIgnoreBlankLines;
48         m_bIgnoreCase = options.bIgnoreCase;
49         m_bIgnoreEOLDifference = options.bIgnoreEol;
50         m_bIgnoreNumbers = options.bIgnoreNumbers;
51 }
52
53 /**
54  * @brief Default constructor.
55  */
56 QuickCompareOptions::QuickCompareOptions()
57 : m_bStopAfterFirstDiff(false)
58 {
59 }
60
61 /**
62  * @brief Default constructor.
63  */
64 DiffutilsOptions::DiffutilsOptions()
65 : m_outputStyle(DIFF_OUTPUT_NORMAL)
66 , m_diffAlgorithm(DIFF_ALGORITHM_DEFAULT)
67 , m_contextLines(0)
68 , m_filterCommentsLines(false)
69 , m_bCompletelyBlankOutIgnoredDiffereneces(false)
70 , m_bIndentHeuristic(true)
71 {
72 }
73
74 /**
75  * @brief Constructor cloning CompareOptions.
76  * @param [in] options CompareOptions instance to clone.
77  */
78 DiffutilsOptions::DiffutilsOptions(const CompareOptions& options)
79 : CompareOptions(options)
80 , m_outputStyle(DIFF_OUTPUT_NORMAL)
81 , m_diffAlgorithm(DIFF_ALGORITHM_DEFAULT)
82 , m_contextLines(0)
83 , m_filterCommentsLines(false)
84 , m_bCompletelyBlankOutIgnoredDiffereneces(false)
85 , m_bIndentHeuristic(true)
86 {
87 }
88
89 /**
90  * @brief Sets options from DIFFOPTIONS structure.
91  * @param [in] options Diffutils options.
92  */
93 void DiffutilsOptions::SetFromDiffOptions(const DIFFOPTIONS & options)
94 {
95         CompareOptions::SetFromDiffOptions(options);
96         m_bCompletelyBlankOutIgnoredDiffereneces = options.bCompletelyBlankOutIgnoredChanges;
97         m_filterCommentsLines = options.bFilterCommentsLines;
98         m_bIndentHeuristic = options.bIndentHeuristic;
99         switch (options.nDiffAlgorithm)
100         {
101         case 0:
102                 m_diffAlgorithm = DIFF_ALGORITHM_DEFAULT;
103                 break;
104         case 1:
105                 m_diffAlgorithm = DIFF_ALGORITHM_MINIMAL;
106                 break;
107         case 2:
108                 m_diffAlgorithm = DIFF_ALGORITHM_PATIENCE;
109                 break;
110         case 3:
111                 m_diffAlgorithm = DIFF_ALGORITHM_HISTOGRAM;
112                 break;
113         case 4:
114                 m_diffAlgorithm = DIFF_ALGORITHM_NONE;
115                 break;
116         default:
117                 throw "Unknown diff algorithm value!";
118         }
119 }
120
121 /**
122  * @brief Set options to diffutils.
123  * Diffutils uses options from global variables we must set. Those variables
124  * aren't most logically named, and most are just int's, with some magic
125  * values and meanings, with fancy combinations? So not easy to setup. This
126  * function maps our easier to handle compare options to diffutils globals.
127  */
128 void DiffutilsOptions::SetToDiffUtils()
129 {
130         switch (m_outputStyle)
131         {
132         case DIFF_OUTPUT_NORMAL:
133                 output_style = OUTPUT_NORMAL;
134                 break;
135         case DIFF_OUTPUT_CONTEXT:
136                 output_style = OUTPUT_CONTEXT;
137                 break;
138         case DIFF_OUTPUT_UNIFIED:
139                 output_style = OUTPUT_UNIFIED;
140                 break;
141         case DIFF_OUTPUT_HTML:
142                 output_style = OUTPUT_HTML;
143                 break;
144         default:
145                 throw "Unknown output style!";
146                 break;
147         }
148
149         context = m_contextLines;
150
151         ignore_space_change_flag = (m_ignoreWhitespace == WHITESPACE_IGNORE_CHANGE);
152         ignore_all_space_flag = (m_ignoreWhitespace == WHITESPACE_IGNORE_ALL);
153         ignore_blank_lines_flag = m_bIgnoreBlankLines;
154         ignore_case_flag = m_bIgnoreCase;
155         ignore_numbers_flag = m_bIgnoreNumbers;
156         ignore_eol_diff = m_bIgnoreEOLDifference;
157         ignore_some_changes = (m_ignoreWhitespace != WHITESPACE_COMPARE_ALL || m_bIgnoreCase || m_bIgnoreBlankLines || m_bIgnoreEOLDifference);
158         length_varies = (m_ignoreWhitespace != WHITESPACE_COMPARE_ALL);
159
160         // We have no interest changing these values, hard-code them.
161         always_text_flag = 0; // diffutils needs to detect binary files
162         horizon_lines = 0;
163         heuristic = 1;
164         recursive = 0;
165
166         no_diff_means_no_output = 0;
167         no_details_flag = 0;
168         line_end_char = '\n';
169         tab_align_flag = 0;
170         tab_expand_flag = 0;
171         paginate_flag = 0;
172         switch_string = NULL;
173         file_label[0] = NULL;
174         file_label[1] = NULL;
175 }
176
177 /**
178  * @brief Gets options to DIFFOPTIONS structure.
179  * @param [out] options Diffutils options.
180  */
181 void DiffutilsOptions::GetAsDiffOptions(DIFFOPTIONS &options) const
182 {
183         options.bCompletelyBlankOutIgnoredChanges = m_bCompletelyBlankOutIgnoredDiffereneces;
184         options.bFilterCommentsLines = m_filterCommentsLines;
185         options.bIgnoreBlankLines = m_bIgnoreBlankLines;
186         options.bIgnoreCase = m_bIgnoreCase;
187         options.bIgnoreEol = m_bIgnoreEOLDifference;
188         options.bIgnoreNumbers = m_bIgnoreNumbers;
189         options.nDiffAlgorithm = m_diffAlgorithm;
190
191         switch (m_ignoreWhitespace)
192         {
193         case WHITESPACE_COMPARE_ALL:
194                 options.nIgnoreWhitespace = 0;
195                 break;
196         case WHITESPACE_IGNORE_CHANGE:
197                 options.nIgnoreWhitespace = 1;
198                 break;
199         case WHITESPACE_IGNORE_ALL:
200                 options.nIgnoreWhitespace = 2;
201                 break;
202         default:
203                 throw "Unknown whitespace ignore value!";
204                 break;
205         }
206 }
207
208 QuickCompareOptions::QuickCompareOptions(const CompareOptions& options)
209 : CompareOptions(options)
210 , m_bStopAfterFirstDiff(false)
211 {
212 }