reactos/sdk/tools/log2lines/revision.c

300 lines
6.9 KiB
C

/*
* ReactOS log2lines
* Written by Jan Roeloffzen
*
* - SVN interface and revision analysis
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "version.h"
#include "compat.h"
#include "util.h"
#include "options.h"
#include "log2lines.h"
static void
log_rev_check(FILE *outFile, char *fileName, int showfile)
{
int rev = 0;
char s[LINESIZE];
strcpy(s, opt_SourcesPath);
strcat(s, fileName);
rev = getRevision(s, 1);
if (!showfile)
s[0] = '\0';
if (revinfo.opt_verbose)
log(outFile, "| R--- %s Last Changed Rev: %d\n", s, rev);
if (rev && opt_Revision_check)
{
if (revinfo.rev < revinfo.buildrev)
{
summ.revconflicts++;
log(outFile, "| R--- Conflict %s: source tree(%d) < build(%d)\n", s, rev, revinfo.buildrev);
}
else if (rev > revinfo.buildrev)
{
summ.revconflicts++;
log(outFile, "| R--- Conflict %s: file(%d) > build(%d)\n", s, rev, revinfo.buildrev);
}
}
}
static void
logRevCheck(FILE *outFile)
{
int twice = 0;
twice = (lastLine.nr2 && strcmp(lastLine.file1, lastLine.file2) != 0);
log_rev_check(outFile, lastLine.file1, twice);
if (twice)
{
log_rev_check(outFile, lastLine.file2, twice);
}
}
int
getRevision(char *fileName, int lastChanged)
{
char s[LINESIZE];
FILE *psvn;
int rev = 0;
if (!fileName)
fileName = opt_SourcesPath;
sprintf(s, "svn info %s", fileName);
if ((psvn = POPEN(s, "r")))
{
while (fgets(s, LINESIZE, psvn))
{
if (lastChanged)
{
if (sscanf(s, "Last Changed Rev: %d", &rev))
break;
}
else
{
if (sscanf(s, "Revision: %d", &rev))
break;
}
}
}
else
l2l_dbg(1, "Can't popen: \"%s\"\n", s);
if (psvn)
PCLOSE(psvn);
return rev;
}
int
getTBRevision(char *fileName)
{
char *s;
int rev = 0;
s = strrchr(fileName, PATH_CHAR);
if (s)
s += 1;
else
s = fileName;
sscanf(s, TRKBUILDPREFIX "%d", &rev);
if (!rev)
{
s = strrchr(fileName, PATH_CHAR);
if (s)
*s = '\0'; // clear, so we have the parent dir
else
{
// where else to look?
fileName = opt_SourcesPath;
}
rev = getRevision(fileName, 1);
if (s)
*s = PATH_CHAR; // restore
}
l2l_dbg(1, "TBRevision: %d\n", rev);
return rev;
}
void
reportRevision(FILE *outFile)
{
if (opt_Revision_check)
{
if (lastLine.valid)
logRevCheck(outFile);
}
}
unsigned long
findRev(FILE *finx, int *rev)
{
unsigned long pos = 0L;
while (!fseek(finx, (*rev) * sizeof(unsigned long), SEEK_SET))
{
fread(&pos, sizeof(long), 1, finx);
(*rev)--;
if (pos)
break;
}
return pos;
}
int
regscan(FILE *outFile)
{
int res = 0;
char logname[PATH_MAX];
char inxname[PATH_MAX];
char line[LINESIZE + 1];
char line2[LINESIZE + 1];
FILE *flog = NULL;
FILE *finx = NULL;
unsigned long pos = 0L;
int r;
sprintf(logname, "%s" PATH_STR "%s", opt_SourcesPath, SVNDB);
sprintf(inxname, "%s" PATH_STR "%s", opt_SourcesPath, SVNDB_INX);
flog = fopen(logname, "rb");
finx = fopen(inxname, "rb");
if (flog && finx)
{
r = revinfo.buildrev;
if (!fread(&pos, sizeof(long), 1, finx))
{
res = 2;
l2l_dbg(0, "Cannot read magic number\n");
}
if (!res)
{
if (pos != MAGIC_INX)
{
res = 3;
l2l_dbg(0, "Incorrect magic number (%lx)\n", pos);
}
}
if (!res)
{
char flag[2];
char path[PATH_MAX];
char path2[PATH_MAX];
int wflag = 0;
clilog(outFile, "Regression candidates:\n");
while (( pos = findRev(finx, &r) ))
{
if (r < (revinfo.buildrev - revinfo.range))
{
l2l_dbg(1, "r%d is outside range of %d revisions\n", r, revinfo.range);
break;
}
fseek(flog, pos, SEEK_SET);
wflag = 1;
fgets(line, LINESIZE, flog);
fgets(line2, LINESIZE, flog);
while (fgets(line2, LINESIZE, flog))
{
path2[0] = '\0';
if (sscanf(line2, "%1s %s %s", flag, path, path2) >= 2)
{
if (entry_lookup(&sources, path) || entry_lookup(&sources, path2))
{
if (wflag == 1)
{
clilog(outFile, "%sChanged paths:\n", line);
summ.regfound++;
wflag = 2;
}
clilog(outFile, "%s", line2);
}
}
else
break;
}
if (wflag == 2)
{
int i = 0;
clilog(outFile, "\n");
while (fgets(line2, LINESIZE, flog))
{
i++;
clilog(outFile, "%s", line2);
if (strncmp(LOGBOTTOM, line2, sizeof(LOGBOTTOM) - 1) == 0)
break;
}
}
}
}
}
else
{
res = 1;
l2l_dbg(0, "Cannot open %s or %s\n", logname, inxname);
}
if (flog)
fclose(flog);
if (finx)
fclose(finx);
return res;
}
int
updateSvnlog(void)
{
int res = 0;
char logname[PATH_MAX];
char inxname[PATH_MAX];
char line[LINESIZE + 1];
FILE *flog = NULL;
FILE *finx = NULL;
unsigned long pos;
int r, y, m, d;
char name[NAMESIZE];
sprintf(logname, "%s" PATH_STR "%s", opt_SourcesPath, SVNDB);
sprintf(inxname, "%s" PATH_STR "%s", opt_SourcesPath, SVNDB_INX);
flog = fopen(logname, "rb");
finx = fopen(inxname, "wb");
if (flog && finx)
{
pos = MAGIC_INX;
fwrite(&pos, sizeof(long), 1, finx);
pos = ftell(flog);
while (fgets(line, LINESIZE, flog))
{
if (sscanf(line, "r%d | %s | %d-%d-%d", &r, name, &y, &m, &d) == 5)
{
l2l_dbg(1, "%ld r%d | %s | %d-%d-%d\n", pos, r, name, y, m, d);
fseek(finx, r * sizeof(unsigned long), SEEK_SET);
fwrite(&pos, sizeof(unsigned long), 1, finx);
}
pos = ftell(flog);
}
}
if (flog)
fclose(flog);
if (finx)
fclose(finx);
return res;
}
/* EOF */