Git conversion: Make reactos the root directory, move rosapps, rostests, wallpapers...
[reactos.git] / sdk / tools / log2lines / revision.c
1 /*
2 * ReactOS log2lines
3 * Written by Jan Roeloffzen
4 *
5 * - SVN interface and revision analysis
6 */
7
8 #include <stdio.h>
9 #include <string.h>
10 #include <stdlib.h>
11
12 #include "version.h"
13 #include "compat.h"
14 #include "util.h"
15 #include "options.h"
16 #include "log2lines.h"
17
18 static void
19 log_rev_check(FILE *outFile, char *fileName, int showfile)
20 {
21 int rev = 0;
22 char s[LINESIZE];
23
24 strcpy(s, opt_SourcesPath);
25 strcat(s, fileName);
26 rev = getRevision(s, 1);
27 if (!showfile)
28 s[0] = '\0';
29 if (revinfo.opt_verbose)
30 log(outFile, "| R--- %s Last Changed Rev: %d\n", s, rev);
31
32 if (rev && opt_Revision_check)
33 {
34 if (revinfo.rev < revinfo.buildrev)
35 {
36 summ.revconflicts++;
37 log(outFile, "| R--- Conflict %s: source tree(%d) < build(%d)\n", s, rev, revinfo.buildrev);
38 }
39 else if (rev > revinfo.buildrev)
40 {
41 summ.revconflicts++;
42 log(outFile, "| R--- Conflict %s: file(%d) > build(%d)\n", s, rev, revinfo.buildrev);
43 }
44 }
45 }
46
47 static void
48 logRevCheck(FILE *outFile)
49 {
50 int twice = 0;
51
52 twice = (lastLine.nr2 && strcmp(lastLine.file1, lastLine.file2) != 0);
53 log_rev_check(outFile, lastLine.file1, twice);
54 if (twice)
55 {
56 log_rev_check(outFile, lastLine.file2, twice);
57 }
58 }
59
60 int
61 getRevision(char *fileName, int lastChanged)
62 {
63 char s[LINESIZE];
64 FILE *psvn;
65 int rev = 0;
66
67 if (!fileName)
68 fileName = opt_SourcesPath;
69 sprintf(s, "svn info %s", fileName);
70 if ((psvn = POPEN(s, "r")))
71 {
72 while (fgets(s, LINESIZE, psvn))
73 {
74 if (lastChanged)
75 {
76 if (sscanf(s, "Last Changed Rev: %d", &rev))
77 break;
78 }
79 else
80 {
81 if (sscanf(s, "Revision: %d", &rev))
82 break;
83 }
84 }
85 }
86 else
87 l2l_dbg(1, "Can't popen: \"%s\"\n", s);
88
89 if (psvn)
90 PCLOSE(psvn);
91
92 return rev;
93 }
94
95 int
96 getTBRevision(char *fileName)
97 {
98 char *s;
99 int rev = 0;
100
101 s = strrchr(fileName, PATH_CHAR);
102 if (s)
103 s += 1;
104 else
105 s = fileName;
106
107 sscanf(s, TRKBUILDPREFIX "%d", &rev);
108 if (!rev)
109 {
110 s = strrchr(fileName, PATH_CHAR);
111 if (s)
112 *s = '\0'; // clear, so we have the parent dir
113 else
114 {
115 // where else to look?
116 fileName = opt_SourcesPath;
117 }
118 rev = getRevision(fileName, 1);
119 if (s)
120 *s = PATH_CHAR; // restore
121 }
122
123 l2l_dbg(1, "TBRevision: %d\n", rev);
124 return rev;
125 }
126
127
128 void
129 reportRevision(FILE *outFile)
130 {
131 if (opt_Revision_check)
132 {
133 if (lastLine.valid)
134 logRevCheck(outFile);
135 }
136 }
137
138 unsigned long
139 findRev(FILE *finx, int *rev)
140 {
141 unsigned long pos = 0L;
142
143 while (!fseek(finx, (*rev) * sizeof(unsigned long), SEEK_SET))
144 {
145 fread(&pos, sizeof(long), 1, finx);
146 (*rev)--;
147 if (pos)
148 break;
149 }
150 return pos;
151 }
152
153 int
154 regscan(FILE *outFile)
155 {
156 int res = 0;
157 char logname[PATH_MAX];
158 char inxname[PATH_MAX];
159 char line[LINESIZE + 1];
160 char line2[LINESIZE + 1];
161 FILE *flog = NULL;
162 FILE *finx = NULL;
163 unsigned long pos = 0L;
164 int r;
165
166 sprintf(logname, "%s" PATH_STR "%s", opt_SourcesPath, SVNDB);
167 sprintf(inxname, "%s" PATH_STR "%s", opt_SourcesPath, SVNDB_INX);
168 flog = fopen(logname, "rb");
169 finx = fopen(inxname, "rb");
170
171 if (flog && finx)
172 {
173 r = revinfo.buildrev;
174 if (!fread(&pos, sizeof(long), 1, finx))
175 {
176 res = 2;
177 l2l_dbg(0, "Cannot read magic number\n");
178 }
179
180 if (!res)
181 {
182 if (pos != MAGIC_INX)
183 {
184 res = 3;
185 l2l_dbg(0, "Incorrect magic number (%lx)\n", pos);
186 }
187 }
188
189 if (!res)
190 {
191 char flag[2];
192 char path[PATH_MAX];
193 char path2[PATH_MAX];
194 int wflag = 0;
195 clilog(outFile, "Regression candidates:\n");
196 while (( pos = findRev(finx, &r) ))
197 {
198 if (r < (revinfo.buildrev - revinfo.range))
199 {
200 l2l_dbg(1, "r%d is outside range of %d revisions\n", r, revinfo.range);
201 break;
202 }
203 fseek(flog, pos, SEEK_SET);
204 wflag = 1;
205 fgets(line, LINESIZE, flog);
206 fgets(line2, LINESIZE, flog);
207 while (fgets(line2, LINESIZE, flog))
208 {
209 path2[0] = '\0';
210 if (sscanf(line2, "%1s %s %s", flag, path, path2) >= 2)
211 {
212 if (entry_lookup(&sources, path) || entry_lookup(&sources, path2))
213 {
214 if (wflag == 1)
215 {
216 clilog(outFile, "%sChanged paths:\n", line);
217 summ.regfound++;
218 wflag = 2;
219 }
220 clilog(outFile, "%s", line2);
221 }
222 }
223 else
224 break;
225 }
226 if (wflag == 2)
227 {
228 int i = 0;
229 clilog(outFile, "\n");
230 while (fgets(line2, LINESIZE, flog))
231 {
232 i++;
233 clilog(outFile, "%s", line2);
234 if (strncmp(LOGBOTTOM, line2, sizeof(LOGBOTTOM) - 1) == 0)
235 break;
236 }
237 }
238 }
239 }
240 }
241 else
242 {
243 res = 1;
244 l2l_dbg(0, "Cannot open %s or %s\n", logname, inxname);
245 }
246
247 if (flog)
248 fclose(flog);
249 if (finx)
250 fclose(finx);
251
252 return res;
253 }
254
255
256 int
257 updateSvnlog(void)
258 {
259 int res = 0;
260 char logname[PATH_MAX];
261 char inxname[PATH_MAX];
262 char line[LINESIZE + 1];
263 FILE *flog = NULL;
264 FILE *finx = NULL;
265 unsigned long pos;
266 int r, y, m, d;
267 char name[NAMESIZE];
268
269 sprintf(logname, "%s" PATH_STR "%s", opt_SourcesPath, SVNDB);
270 sprintf(inxname, "%s" PATH_STR "%s", opt_SourcesPath, SVNDB_INX);
271 flog = fopen(logname, "rb");
272 finx = fopen(inxname, "wb");
273
274 if (flog && finx)
275 {
276 pos = MAGIC_INX;
277 fwrite(&pos, sizeof(long), 1, finx);
278 pos = ftell(flog);
279 while (fgets(line, LINESIZE, flog))
280 {
281 if (sscanf(line, "r%d | %s | %d-%d-%d", &r, name, &y, &m, &d) == 5)
282 {
283 l2l_dbg(1, "%ld r%d | %s | %d-%d-%d\n", pos, r, name, y, m, d);
284 fseek(finx, r * sizeof(unsigned long), SEEK_SET);
285 fwrite(&pos, sizeof(unsigned long), 1, finx);
286 }
287 pos = ftell(flog);
288 }
289 }
290
291 if (flog)
292 fclose(flog);
293 if (finx)
294 fclose(finx);
295
296 return res;
297 }
298
299 /* EOF */