/* * ReactOS log2lines * Written by Jan Roeloffzen * * - SVN interface and revision analysis */ #include #include #include #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 */