Mercurial > projects > qtd
comparison generator/fileout.cpp @ 1:e78566595089
initial import
author | mandel |
---|---|
date | Mon, 11 May 2009 16:01:50 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
0:36fb74dc547d | 1:e78566595089 |
---|---|
1 /**************************************************************************** | |
2 ** | |
3 ** Copyright (C) 1992-2008 Nokia. All rights reserved. | |
4 ** | |
5 ** This file is part of Qt Jambi. | |
6 ** | |
7 ** * Commercial Usage | |
8 * Licensees holding valid Qt Commercial licenses may use this file in | |
9 * accordance with the Qt Commercial License Agreement provided with the | |
10 * Software or, alternatively, in accordance with the terms contained in | |
11 * a written agreement between you and Nokia. | |
12 * | |
13 * | |
14 * GNU General Public License Usage | |
15 * Alternatively, this file may be used under the terms of the GNU | |
16 * General Public License versions 2.0 or 3.0 as published by the Free | |
17 * Software Foundation and appearing in the file LICENSE.GPL included in | |
18 * the packaging of this file. Please review the following information | |
19 * to ensure GNU General Public Licensing requirements will be met: | |
20 * http://www.fsf.org/licensing/licenses/info/GPLv2.html and | |
21 * http://www.gnu.org/copyleft/gpl.html. In addition, as a special | |
22 * exception, Nokia gives you certain additional rights. These rights | |
23 * are described in the Nokia Qt GPL Exception version 1.2, included in | |
24 * the file GPL_EXCEPTION.txt in this package. | |
25 * | |
26 * Qt for Windows(R) Licensees | |
27 * As a special exception, Nokia, as the sole copyright holder for Qt | |
28 * Designer, grants users of the Qt/Eclipse Integration plug-in the | |
29 * right for the Qt/Eclipse Integration to link to functionality | |
30 * provided by Qt Designer and its related libraries. | |
31 * | |
32 * | |
33 * If you are unsure which license is appropriate for your use, please | |
34 * contact the sales department at qt-sales@nokia.com. | |
35 | |
36 ** | |
37 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE | |
38 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. | |
39 ** | |
40 ****************************************************************************/ | |
41 | |
42 #include "fileout.h" | |
43 #include "reporthandler.h" | |
44 | |
45 #include <QFileInfo> | |
46 #include <QDir> | |
47 | |
48 bool FileOut::dummy = false; | |
49 bool FileOut::diff = false; | |
50 | |
51 #ifdef Q_OS_LINUX | |
52 const char* colorDelete = "\033[31m"; | |
53 const char* colorAdd = "\033[32m"; | |
54 const char* colorInfo = "\033[36m"; | |
55 const char* colorReset = "\033[0m"; | |
56 #else | |
57 const char* colorDelete = ""; | |
58 const char* colorAdd = ""; | |
59 const char* colorInfo = ""; | |
60 const char* colorReset = ""; | |
61 #endif | |
62 | |
63 FileOut::FileOut(QString n): | |
64 m_name(n), | |
65 stream(&tmp), | |
66 isDone(false) | |
67 {} | |
68 | |
69 static int* lcsLength(QList<QByteArray> a, QList<QByteArray> b) { | |
70 const int height = a.size() + 1; | |
71 const int width = b.size() + 1; | |
72 | |
73 int *res = new int[width * height]; | |
74 | |
75 for (int row=0; row<height; row++) { | |
76 res[width * row] = 0; | |
77 } | |
78 for (int col=0; col<width; col++) { | |
79 res[col] = 0; | |
80 } | |
81 | |
82 for (int row=1; row<height; row++) { | |
83 for (int col=1; col<width; col++) { | |
84 | |
85 if (a[row-1] == b[col-1]) | |
86 res[width * row + col] = res[width * (row-1) + col-1] + 1; | |
87 else | |
88 res[width * row + col] = qMax(res[width * row + col-1], | |
89 res[width * (row-1) + col]); | |
90 } | |
91 } | |
92 return res; | |
93 } | |
94 | |
95 enum Type {Add, Delete, Unchanged}; | |
96 | |
97 struct Unit | |
98 { | |
99 Unit(Type type, int pos) : | |
100 type(type), | |
101 start(pos), | |
102 end(pos) | |
103 {} | |
104 | |
105 Type type; | |
106 int start; | |
107 int end; | |
108 | |
109 void print(QList<QByteArray> a, QList<QByteArray> b){ | |
110 { | |
111 if (type == Unchanged) { | |
112 if ((end - start) > 9) { | |
113 for (int i = start; i <= start+2; i++) | |
114 printf(" %s\n", a[i].data()); | |
115 printf("%s=\n= %d more lines\n=%s\n", colorInfo, end - start - 6, colorReset); | |
116 for (int i = end-2; i <= end; i++) | |
117 printf(" %s\n", a[i].data()); | |
118 } | |
119 else | |
120 for (int i = start; i <= end; i++) | |
121 printf(" %s\n", a[i].data()); | |
122 } | |
123 else if(type == Add) { | |
124 printf("%s", colorAdd); | |
125 for (int i = start; i <= end; i++){ | |
126 printf("+ %s\n", b[i].data()); | |
127 } | |
128 printf("%s", colorReset); | |
129 } | |
130 else if (type == Delete) { | |
131 printf("%s", colorDelete); | |
132 for (int i = start; i <= end; i++) { | |
133 printf("- %s\n", a[i].data()); | |
134 } | |
135 printf("%s", colorReset); | |
136 } | |
137 } | |
138 } | |
139 }; | |
140 | |
141 static QList<Unit*> *unitAppend(QList<Unit*> *res, Type type, int pos) | |
142 { | |
143 if (res == 0) { | |
144 res = new QList<Unit*>; | |
145 res->append(new Unit(type, pos)); | |
146 return res; | |
147 } | |
148 | |
149 Unit *last = res->last(); | |
150 if (last->type == type) { | |
151 last->end = pos; | |
152 } else { | |
153 res->append(new Unit(type, pos)); | |
154 } | |
155 return res; | |
156 } | |
157 | |
158 static QList<Unit*> *diffHelper(int *lcs, QList<QByteArray> a, QList<QByteArray> b, int row, int col) { | |
159 if (row>0 && col>0 && (a[row-1] == b[col-1])) { | |
160 return unitAppend(diffHelper(lcs, a, b, row-1, col-1), Unchanged, row-1); | |
161 } | |
162 else { | |
163 int width = b.size()+1; | |
164 if ((col > 0) && ((row==0) || | |
165 lcs[width * row + col-1] >= lcs[width * (row-1) + col])) | |
166 { | |
167 return unitAppend(diffHelper(lcs, a, b, row, col-1), Add, col-1); | |
168 } | |
169 else if((row > 0) && ((col==0) || | |
170 lcs[width * row + col-1] < lcs[width * (row-1) + col])){ | |
171 return unitAppend(diffHelper(lcs, a, b, row-1, col), Delete, row-1);; | |
172 } | |
173 } | |
174 delete lcs; | |
175 return 0; | |
176 } | |
177 | |
178 static void diff(QList<QByteArray> a, QList<QByteArray> b) { | |
179 QList<Unit*> *res = diffHelper(lcsLength(a, b), a, b, a.size(), b.size()); | |
180 for (int i=0; i < res->size(); i++) { | |
181 Unit *unit = res->at(i); | |
182 unit->print(a, b); | |
183 delete(unit); | |
184 } | |
185 delete(res); | |
186 } | |
187 | |
188 | |
189 bool FileOut::done() { | |
190 Q_ASSERT( !isDone ); | |
191 isDone = true; | |
192 bool fileEqual = false; | |
193 QFile fileRead(m_name); | |
194 QFileInfo info(fileRead); | |
195 stream.flush(); | |
196 QByteArray original; | |
197 if (info.exists() && (diff || (info.size() == tmp.size()))) { | |
198 if ( !fileRead.open(QIODevice::ReadOnly) ) { | |
199 ReportHandler::warning(QString("failed to open file '%1' for reading") | |
200 .arg(fileRead.fileName())); | |
201 return false; | |
202 } | |
203 | |
204 original = fileRead.readAll(); | |
205 fileRead.close(); | |
206 fileEqual = (original == tmp); | |
207 } | |
208 | |
209 if( !fileEqual ) { | |
210 if( !FileOut::dummy ) { | |
211 QDir dir(info.absolutePath()); | |
212 if (!dir.mkpath(dir.absolutePath())) { | |
213 ReportHandler::warning(QString("unable to create directory '%1'") | |
214 .arg(dir.absolutePath())); | |
215 return false; | |
216 } | |
217 | |
218 QFile fileWrite(m_name); | |
219 if (!fileWrite.open(QIODevice::WriteOnly)) { | |
220 ReportHandler::warning(QString("failed to open file '%1' for writing") | |
221 .arg(fileWrite.fileName())); | |
222 return false; | |
223 } | |
224 stream.setDevice(&fileWrite); | |
225 stream << tmp; | |
226 } | |
227 if (diff) { | |
228 printf("%sFile: %s%s\n", colorInfo, qPrintable(m_name), colorReset); | |
229 | |
230 ::diff(original.split('\n'), tmp.split('\n')); | |
231 | |
232 printf("\n"); | |
233 } | |
234 return true; | |
235 } | |
236 return false; | |
237 } |