Index: tools/rsym/log2lines.c =================================================================== --- tools/rsym/log2lines.c (revision 44454) +++ tools/rsym/log2lines.c (working copy) @@ -10,15 +10,19 @@ #include "rsym.h" -#define LOG2LINES_VERSION "1.5" +#define LOG2LINES_VERSION "1.6" #define INVALID_BASE 0xFFFFFFFFL #define DEF_OPT_DIR "output-i386" #define SOURCES_ENV "_ROSBE_ROSSOURCEDIR" +#define CACHEFILE "log2lines.cache" +#define TRKBUILDPREFIX "bootcd-" #if defined (__DJGPP__) || defined (__WIN32__) +#define POPEN _popen +#define PCLOSE _pclose #define DEV_NULL "NUL" #define DOS_PATHS #define PATH_CHAR '\\' @@ -33,6 +37,8 @@ #include #define MAX_PATH PATH_MAX +#define POPEN popen +#define PCLOSE pclose #define DEV_NULL "/dev/null" #define UNIX_PATHS #define PATH_CHAR '/' @@ -46,8 +52,7 @@ #define CP_FMT CP_CMD "%s %s > " DEV_NULL #define CMD_7Z "7z" -//#define UNZIP_FMT_7Z "%s e -y %s -o%s > " DEV_NULL -#define UNZIP_FMT_7Z "%s e -y %s -o%s" +#define UNZIP_FMT_7Z "%s e -y %s -o%s > " DEV_NULL #define UNZIP_FMT "%s x -y -r %s -o%s > " DEV_NULL #define UNZIP_FMT_CAB \ "%s x -y -r %s" PATH_STR "reactos" PATH_STR "reactos.cab -o%s" PATH_STR "reactos" PATH_STR "reactos > " DEV_NULL @@ -62,6 +67,12 @@ fprintf(logFile, fmt, ##__VA_ARGS__); \ } +#define l2l_dbg(level, ...) \ + { \ + if (opt_verbose >= level) \ + fprintf(stderr, ##__VA_ARGS__); \ + } + struct entry_struct { char *buf; @@ -88,6 +99,7 @@ int skipped; int diff; int majordiff; + int revconflicts; int offset_errors; int total; }; @@ -103,17 +115,26 @@ int nr2; }; +struct revinfo_struct +{ + int rev; + int buildrev; + int opt_verbose; +}; + typedef struct cache_struct CACHE; typedef struct summ_struct SUMM; -typedef struct lineinfo_struct LINEINFO; +typedef struct lineinfo_struct LINEINFO; +typedef struct revinfo_struct REVINFO; static CACHE cache; static SUMM summ; static LINEINFO lastLine; +static REVINFO revinfo; -static char *optchars = "bcd:fFhl:mMrsS:tTuUvz:"; -static int opt_buffered= 0; // -b -static int opt_help = 0; // -h +static char *optchars = "bcd:fFhl:mMrR:sS:tTuUvz:"; +static int opt_buffered = 0; // -b +static int opt_help = 0; // -h static int opt_force = 0; // -f static int opt_exit = 0; // -e static int opt_verbose = 0; // -v @@ -122,14 +143,16 @@ static int opt_Mark = 0; // -M static int opt_raw = 0; // -r static int opt_stats = 0; // -s -static int opt_Source = 0; // -S +static int opt_Source = 0; // -S [+][,] +static int opt_SrcPlus = 0; // -S [+][,] static int opt_twice = 0; // -t static int opt_Twice = 0; // -T static int opt_undo = 0; // -u static int opt_redo = 0; // -U -static char opt_dir[MAX_PATH]; // -d -static char opt_logFile[MAX_PATH]; // -l -static char opt_7z[MAX_PATH]; // -z +static char *opt_Revision= NULL; // -R +static char opt_dir[MAX_PATH]; // -d +static char opt_logFile[MAX_PATH]; // -l +static char opt_7z[MAX_PATH]; // -z static char opt_scanned[LINESIZE]; // all scanned options static FILE *logFile = NULL; @@ -138,36 +161,121 @@ static char sources_path[LINESIZE]; +static int +file_exists(char *name) +{ + FILE *f; + + f = fopen(name, "r"); + if (!f) + return 0; + fclose(f); + return 1; +} + static void clearLastLine(void) { memset(&lastLine, 0, sizeof(LINEINFO)); } +static int +getRevision(char *fileName, int lastChanged) +{ + char s[LINESIZE]; + FILE *psvn; + int rev = 0; + + if (!fileName) + fileName = sources_path; + 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; +} + +static 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 = sources_path; + } + rev = getRevision(fileName, 1); + if (s) + *s = PATH_CHAR; //restore + } + + l2l_dbg(1,"TBRevision: %d\n", rev); + return rev; +} + static void -log_file(FILE *outFile, char *fileName, int max ) +log_file(FILE * outFile, char *fileName, int line ) { - int i = 0, min = 0; + int i=0, min=0, max=0; char s[LINESIZE]; - char p[LINESIZE]; FILE *src; - strcpy(p, sources_path); - strcat(p, fileName); - if ((src = fopen(p, "r"))) + strcpy(s, sources_path); + strcat(s, fileName); + + max = line + opt_SrcPlus; + if ((src = fopen(s, "r"))) { - min = max - opt_Source; + min + = line - opt_Source; min = (min < 0) ? 0 : min; while (i < max && fgets(s, LINESIZE, src)) { if (i >= min) - log(outFile, "| %4.4d %s", i + 1, s); - i++; + { + if (i == line) + log(outFile, "| ----\n"); + log(outFile, "| %4.4d %s", i+1, s); + } + i ++; } fclose(src); } - else if (opt_verbose) - fprintf(stderr, "Can't open: %s (check " SOURCES_ENV ")\n", p); + else + l2l_dbg(1,"Can't open: %s (check " SOURCES_ENV ")\n", s); } static void @@ -187,12 +295,61 @@ if (!opt_Source) return; if (lastLine.valid) - { logSource(outFile); - } clearLastLine(); } +static void +log_rev(FILE * outFile, char *fileName, int showfile) +{ + int rev = 0; + char s[LINESIZE]; + + strcpy(s, sources_path); + 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) + { + 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 +logRev(FILE *outFile) +{ + int twice = 0; + + twice = (lastLine.nr2 && (strcmp(lastLine.file1,lastLine.file2) != 0)); + log_rev(outFile, lastLine.file1, twice); + if (twice) + { + log_rev(outFile, lastLine.file2, twice); + } +} + +static void +reportRevision(FILE *outFile) +{ + if (strcmp(opt_Revision, "check") != 0) + return; + if (lastLine.valid) + logRev(outFile); +} + static char * basename(char *path) { @@ -200,9 +357,7 @@ base = strrchr(path, PATH_CHAR); if (base) - { return ++base; - } return path; } @@ -241,9 +396,7 @@ if (!i--) return NULL; else - { return &Entries[i]; - } } } return NULL; @@ -374,7 +527,7 @@ PEDosHeader = (PIMAGE_DOS_HEADER)FileData; if (PEDosHeader->e_magic != IMAGE_DOS_MAGIC || PEDosHeader->e_lfanew == 0L) { - fprintf(stderr, "Input file is not a PE image.\n"); + l2l_dbg(0, "Input file is not a PE image.\n"); summ.offset_errors++; return 1; } @@ -397,7 +550,7 @@ PERosSymSectionHeader = find_rossym_section(PEFileHeader, PESectionHeaders); if (!PERosSymSectionHeader) { - fprintf(stderr, "Couldn't find rossym section in executable\n"); + l2l_dbg(0, "Couldn't find rossym section in executable\n"); summ.offset_errors++; return 1; } @@ -405,14 +558,10 @@ if (res) { if (toString) - { - sprintf(toString, "??:0\n"); - } + sprintf(toString, "??:0"); else - { - printf("??:0\n"); - } - fprintf(stderr, "Offset not found.\n"); + printf("??:0"); + l2l_dbg(1, "Offset not found: %x\n", offset); summ.offset_errors++; } @@ -462,37 +611,22 @@ } static int -file_exists(char *name) -{ - FILE *f; - - f = fopen(name, "r"); - if (!f) - { - return 0; - } - fclose(f); - return 1; -} - -static int copy_file(char *src, char *dst) { char Line[LINESIZE]; sprintf(Line, CP_FMT, src, dst); - if (opt_verbose > 1) - fprintf(stderr, "Executing: %s\n", Line); + l2l_dbg(2, "Executing: %s\n", Line); remove(dst); if (file_exists(dst)) { - fprintf(stderr, "Cannot remove dst %s before copy\n", dst); + l2l_dbg(0, "Cannot remove dst %s before copy\n", dst); return 1; } system(Line); if (!file_exists(dst)) { - fprintf(stderr, "Dst %s does not exist after copy \n", dst); + l2l_dbg(0, "Dst %s does not exist after copy \n", dst); return 2; } return 0; @@ -508,7 +642,7 @@ FileData = load_file(file_name, &FileSize); if (!FileData) { - fprintf(stderr, "An error occured loading '%s'\n", file_name); + l2l_dbg(0, "An error occured loading '%s'\n", file_name); } else { @@ -533,16 +667,14 @@ fr = fopen(fname, "rb"); if (!fr) { - if (opt_verbose > 2) - fprintf(stderr, "get_ImageBase, cannot open '%s' (%s)\n", fname, strerror(errno)); + l2l_dbg(3, "get_ImageBase, cannot open '%s' (%s)\n", fname, strerror(errno)); return 1; } readLen = fread(&PEDosHeader, sizeof(IMAGE_DOS_HEADER), 1, fr); if (1 != readLen) { - if (opt_verbose) - fprintf(stderr, "get_ImageBase %s, read error IMAGE_DOS_HEADER (%s)\n", fname, strerror(errno)); + l2l_dbg(1, "get_ImageBase %s, read error IMAGE_DOS_HEADER (%s)\n", fname, strerror(errno)); fclose(fr); return 2; } @@ -550,8 +682,7 @@ /* Check if MZ header exists */ if (PEDosHeader.e_magic != IMAGE_DOS_MAGIC || PEDosHeader.e_lfanew == 0L) { - if (opt_verbose > 1) - fprintf(stderr, "get_ImageBase %s, MZ header missing\n", fname); + l2l_dbg(2, "get_ImageBase %s, MZ header missing\n", fname); fclose(fr); return 3; } @@ -561,8 +692,7 @@ readLen = fread(&PEFileHeader, sizeof(IMAGE_FILE_HEADER), 1, fr); if (1 != readLen) { - if (opt_verbose) - fprintf(stderr, "get_ImageBase %s, read error IMAGE_FILE_HEADER (%s)\n", fname, strerror(errno)); + l2l_dbg(1, "get_ImageBase %s, read error IMAGE_FILE_HEADER (%s)\n", fname, strerror(errno)); fclose(fr); return 4; } @@ -571,8 +701,7 @@ readLen = fread(&PEOptHeader, sizeof(IMAGE_OPTIONAL_HEADER), 1, fr); if (1 != readLen) { - if (opt_verbose) - fprintf(stderr, "get_ImageBase %s, read error IMAGE_OPTIONAL_HEADER (%s)\n", fname, strerror(errno)); + l2l_dbg(1, "get_ImageBase %s, read error IMAGE_OPTIONAL_HEADER (%s)\n", fname, strerror(errno)); fclose(fr); return 5; } @@ -581,8 +710,7 @@ if (PEOptHeader.Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC && PEOptHeader.Magic != IMAGE_NT_OPTIONAL_HDR64_MAGIC) { - if (opt_verbose > 1) - fprintf(stderr, "get_ImageBase %s, not an IMAGE_NT_OPTIONAL_HDR<32|64>\n", fname); + l2l_dbg(2, "get_ImageBase %s, not an IMAGE_NT_OPTIONAL_HDR<32|64>\n", fname); fclose(fr); return 6; } @@ -633,8 +761,7 @@ pentry->buf = s = malloc(l + 1); if (!s) { - if (opt_verbose) - fprintf(stderr, "Alloc entry failed\n"); + l2l_dbg(1, "Alloc entry failed\n"); return entry_delete(pentry); } @@ -646,8 +773,7 @@ s = strchr(s, '|'); if (!s) { - if (opt_verbose) - fprintf(stderr, "Name field missing\n"); + l2l_dbg(1, "Name field missing\n"); return entry_delete(pentry); } *s++ = '\0'; @@ -656,15 +782,13 @@ s = strchr(s, '|'); if (!s) { - if (opt_verbose) - fprintf(stderr, "Path field missing\n"); + l2l_dbg(1, "Path field missing\n"); return entry_delete(pentry); } *s++ = '\0'; if (1 != sscanf(s, "%x", &pentry->ImageBase)) { - if (opt_verbose) - fprintf(stderr, "ImageBase field missing\n"); + l2l_dbg(1, "ImageBase field missing\n"); return entry_delete(pentry); } return pentry; @@ -706,8 +830,7 @@ Line = malloc(LINESIZE + 1); if (!Line) { - if (opt_verbose) - fprintf(stderr, "Alloc Line failed\n"); + l2l_dbg(1, "Alloc Line failed\n"); return 1; } Line[LINESIZE] = '\0'; @@ -715,8 +838,7 @@ fr = fopen(cache_name, "r"); if (!fr) { - if (opt_verbose) - fprintf(stderr, "Open %s failed\n", cache_name); + l2l_dbg(1, "Open %s failed\n", cache_name); free(Line); return 2; } @@ -727,13 +849,10 @@ pentry = entry_create(Line); if (!pentry) { - if (opt_verbose > 1) - fprintf(stderr, "** FAILED: %s\n", Line); + l2l_dbg(2, "** Create entry failed of: %s\n", Line); } else - { entry_insert(pentry); - } } fclose(fr); @@ -751,31 +870,27 @@ if ((fw = fopen(tmp_name, "w")) == NULL) { - if (opt_verbose) - fprintf(stderr, "Apparently %s is not writable (mounted ISO?), using current dir\n", tmp_name); + l2l_dbg(1, "Apparently %s is not writable (mounted ISO?), using current dir\n", tmp_name); cache_name = basename(cache_name); tmp_name = basename(tmp_name); } else { - if (opt_verbose > 2) - fprintf(stderr, "%s is writable\n", tmp_name); + l2l_dbg(3, "%s is writable\n", tmp_name); fclose(fw); remove(tmp_name); } if (force) { - if (opt_verbose > 2) - fprintf(stderr, "Removing %s ...\n", cache_name); + l2l_dbg(3, "Removing %s ...\n", cache_name); remove(cache_name); } else { if (file_exists(cache_name)) { - if (opt_verbose > 2) - fprintf(stderr, "Cache %s already exists\n", cache_name); + l2l_dbg(3, "Cache %s already exists\n", cache_name); return 0; } } @@ -786,10 +901,11 @@ Line[LINESIZE] = '\0'; remove(tmp_name); - fprintf(stderr, "Scanning %s ...\n", opt_dir); + l2l_dbg(0, "Scanning %s ...\n", opt_dir); snprintf(Line, LINESIZE, DIR_FMT, opt_dir, tmp_name); + l2l_dbg(1, "Executing: %s\n", Line); system(Line); - fprintf(stderr, "Creating cache ..."); + l2l_dbg(0, "Creating cache ..."); if ((fr = fopen(tmp_name, "r")) != NULL) { @@ -811,20 +927,15 @@ Fname++; if (*Fname && !skipImageBase) { - if ((err = get_ImageBase(Line, &ImageBase)) != 0) - { - if (opt_verbose > 2) - fprintf(stderr, "%s|%s|%0x, ERR=%d\n", Fname, Line, ImageBase, err); - } + if ((err = get_ImageBase(Line, &ImageBase)) == 0) + fprintf(fw, "%s|%s|%0x\n", Fname, Line, ImageBase); else - { - fprintf(fw, "%s|%s|%0x\n", Fname, Line, ImageBase); - } + l2l_dbg(3, "%s|%s|%0x, ERR=%d\n", Fname, Line, ImageBase, err); } } fclose(fw); } - fprintf(stderr, "... done\n"); + l2l_dbg(0, "... done\n"); fclose(fr); } remove(tmp_name); @@ -847,9 +958,7 @@ */ dpath = path = convert_path(cpath); if (!path) - { return 1; - } // The path could be absolute: if (get_ImageBase(path, &base)) @@ -861,15 +970,13 @@ base = pentry->ImageBase; if (base == INVALID_BASE) { - if (opt_verbose) - fprintf(stderr, "No, or invalid base address: %s\n", path); + l2l_dbg(1, "No, or invalid base address: %s\n", path); res = 2; } } else { - if (opt_verbose) - fprintf(stderr, "Not found in cache: %s\n", path); + l2l_dbg(1, "Not found in cache: %s\n", path); res = 3; } } @@ -920,7 +1027,7 @@ /* Strip all lines added by this tool: */ char buf[NAMESIZE]; if (sscanf(s, "| %s", buf) == 1) - if (buf[0] == '0' || strcmp(buf, "----") == 0 || atoi(buf)) + if (buf[0] == '0' || strcmp(buf, "----") == 0 || strcmp(buf, "R---") == 0 || atoi(buf)) res = 0; } @@ -1001,6 +1108,7 @@ fprintf(outFile, "Skipped: %d\n", summ.skipped); fprintf(outFile, "Differ: %d\n", summ.diff); fprintf(outFile, "Differ (function/source): %d\n", summ.majordiff); + fprintf(outFile, "Revision conflicts: %d\n", summ.revconflicts); fprintf(outFile, "Offset error: %d\n", summ.offset_errors); fprintf(outFile, "Total: %d\n", summ.total); fprintf(outFile, "-------------------------------\n"); @@ -1037,6 +1145,7 @@ translate_line(outFile, Line, path, LineOut); i = 0; translate_char(c, outFile); + reportRevision(outFile); reportSource(outFile); break; case '<': @@ -1058,9 +1167,7 @@ } } else - { translate_char(c, outFile); - } i = 0; break; default: @@ -1078,15 +1185,11 @@ } } else - { translate_char(c, outFile); - } } } else - { translate_char(c, outFile); - } } } else @@ -1096,12 +1199,11 @@ if (!opt_raw) { translate_line(outFile, Line, path, LineOut); + reportRevision(outFile); reportSource(outFile); } else - { log(outFile, "%s", Line); - } } } } @@ -1123,7 +1225,7 @@ " When are given, log2lines works like raddr2line:\n" " - The combination can be repeated\n" " - Also, can be repeated for each \n" -" - NOTE: some of the options below will have no effect in this form.\n" +" - NOTE: Some of the options below will have no effect in this form.\n" " Otherwise it reads stdin and tries to translate lines of the form:\n" " \n\n" " The result is written to stdout.\n" @@ -1132,12 +1234,12 @@ " base address are cached.\n\n" "Options:\n" " -b Use this combined with '-l'. Enable buffering on logFile.\n" -" This may solve loosing output on real hardware.\n\n" +" This may solve loosing output on real hardware (ymmv).\n\n" " -c Console mode. Outputs text per character instead of per line.\n" " This is slightly slower but enables to see what you type.\n\n" " -d |\n" -" Directory to scan for images. (Do not append a '" PATH_STR "')\n" -" This option also takes an ISO image as argument:\n" +" : Directory to scan for images. (Do not append a '" PATH_STR "')\n" +" : This option also takes an ISO image as argument:\n" " - The image is recognized by the '.iso' or '.7z' extension.\n" " - NOTE: The '.7z' and extracted '.iso' basenames must be identical,\n" " which is normally true for Reactos trunk builds.\n" @@ -1150,12 +1252,21 @@ " -F As -f but exits immediately after creating cache.\n\n" " -h This text.\n\n" " -l \n" -" Append copy to specified logFile.\n" +" : Append copy to specified logFile.\n" " Default: no logFile\n\n" " -m Prefix (mark) each translated line with '* '.\n\n" " -M Prefix (mark) each NOT translated line with '? '.\n" " ( Only for lines of the form: )\n\n" " -r Raw output without translation.\n\n" +" -R \n" +" Revision commands interfacing with SVN. is one of:\n" +" - check:\n" +" To be combined with -S. Check each source file in the log and issue\n" +" a warning if its revision is higher than that of the tested build.\n" +" Also when the revison of the source tree is lower than that of the\n" +" tested build (for every source file).\n" +" In both cases the source file's -S output would be unreliable.\n" +" Can be combined with -tTS.\n\n" " -s Statistics. A summary with the following info is printed after EOF:\n" " *** LOG2LINES SUMMARY ***\n" " - Translated: Translated lines.\n" @@ -1164,24 +1275,29 @@ " - Skipped: Lines not translated.\n" " - Differ: Lines where (addr-1) info differs. See -tT options\n" " - Differ(func/src):Lines where also function or source info differ.\n" +" - Rev conflicts: Source files conflicting with build. See '-R check'\n" " - Offset error: Image exists, but error retrieving offset info.\n" " - Total: Total number of lines attempted to translate.\n" " Also some version info is displayed.\n\n" -" -S \n" -" Source lines. Display up to lines until linenumber.\n" -" The environment variable _ROSBE_ROSSOURCEDIR should be correctly set.\n" +" -S [+][,]\n" +" Source line options:\n" +" : Source lines. Display up to lines until linenumber.\n" +" : Optional. Display additional lines after linenumber.\n" +" : Optional. Specify alternate source tree.\n" +" The environment variable " SOURCES_ENV " should be correctly set\n" +" or specify . Use double quotes if the path contains spaces.\n" " For a reliable result, these sources should be up to date with\n" -" the revision you test.\n" -" Can be combined with -tT.\n" -" Implies -U. Retranslation needed for retrieving source info.\n\n" -" -t Translate twice. The address itself and for (address - 1).\n" +" the tested revision (or try '-R check').\n" +" Can be combined with -tTR.\n" +" Implies -U (For retrieving source info).\n\n" +" -t Translate twice. The address itself and for (address-1).\n" " Show extra filename, func and linenumber between [..] if they differ\n" " So if only the linenumbers differ, then only show the extra\n" " linenumber.\n\n" -" -T As -t, but show only filename+func+linenumber for (address - 1.)\n\n" +" -T As -t, but show only filename+func+linenumber for (address-1)\n\n" " -u Undo translations.\n" " Lines are translated back (reverted) to the form \n" -" Also removes all lines previously added by this tool (see -S)\n\n" +" Also removes all lines previously added by this tool (e.g. see -S)\n\n" " -U Undo and reprocess.\n" " Reverted to the form , and then retranslated\n" " Implies -u.\n\n" @@ -1189,11 +1305,11 @@ " Repeating this option adds more verbosity.\n" " Default: only (major) errors\n\n" " -z \n" -" Specify path to 7z. See also option -d.\n" +" : Specify path to 7z. See also option -d.\n" " Default: '7z'\n" "\n" "Examples:\n" -" Setup is a VMware machine with its serial port set to: '\\\\.\\pipe\\kdbg'.\n\n" +" Setup: A VMware machine with its serial port set to: '\\\\.\\pipe\\kdbg'.\n\n" " Just recreate cache after a svn update or a new module has been added:\n" " log2lines -F\n\n" " Use kdbg debugger via console (interactive):\n" @@ -1205,21 +1321,41 @@ " Re-translate a debug log:\n" " log2lines -U -d bootcd-38701-dbg.iso < bugxxxx.log\n\n" " Re-translate a debug log. Specify a 7z file, which wil be decompressed.\n" -" Also check for (address) - (address - 1) differences:\n" +" Also check for (address) - (address-1) differences:\n" " log2lines -U -t -d bootcd-38701-dbg.7z < bugxxxx.log\n" -" This would generate loglines like:\n" -" ''\n\n" -" The following command line invocations are equivalent:\n" +" Output:\n" +" \n\n" +" The following commands are equivalent:\n" " log2lines msi.dll 2e35d msi.dll 2235 msiexec.exe 30a8 msiexec.exe 2e89\n" " log2lines msi.dll 2e35d 2235 msiexec.exe 30a8 2e89\n\n" " Generate source lines from backtrace ('bt') output. Show 2 lines of context:\n" " log2lines -S 2 -d bootcd-38701-dbg.7z < bugxxxx.log\n" +" Output:\n" " \n" " | 0258 #else\n" " | 0259 mainret = main (\n" " \n" " | 0159 return __tmainCRTStartup ();\n" -" | 0160 }\n" +" | 0160 }\n\n" +" Generate source lines. Show 2 lines of context plus 1 additional line and\n" +" specify an alternate source tree:\n" +" log2lines -S 2+1,\"c:\\ros trees\\r44000\" -d bootcd-44000-dbg < dbg.log\n" +" Output:\n" +" \n" +" | 0188 {\n" +" | 0189 r = MSI_ViewFetch( view, &rec );\n" +" | ----\n" +" | 0190 if( r != ERROR_SUCCESS )\n\n" +" Use '-R check' to show that action.c has been changed after the build:\n" +" log2lines -s -d bootcd-43850-dbg.iso -R check -S 2 < dbg.log\n" +" Output:\n" +" \n" +" | 0780 if (create)\n" +" | 0781 rc = RegCreateKeyW(HKEY_LOCAL_MACHINE, keypath, key);\n" +" \n" +" | R--- Conflict : source(44191) > build(43850)\n" +" | 2664 else\n" +" | 2665 rc = MSIREG_OpenUserDataKey(comp->ComponentId,\n" "\n"; static void @@ -1228,13 +1364,9 @@ fprintf(stderr, "log2lines " LOG2LINES_VERSION "\n\n"); fprintf(stderr, "Usage: log2lines -%s { {}}\n", optchars); if (verbose) - { fprintf(stderr, "%s", verboseUsage); - } else - { fprintf(stderr, "Try log2lines -h\n"); - } } static int @@ -1249,8 +1381,7 @@ strcpy(iso_tmp, iso); if ((fiso = fopen(iso, "a")) == NULL) { - if (opt_verbose) - fprintf(stderr, "Open of %s failed (locked for writing?), trying to copy first\n", iso); + l2l_dbg(1, "Open of %s failed (locked for writing?), trying to copy first\n", iso); strcat(iso_tmp, "~"); if (copy_file(iso, iso_tmp)) @@ -1258,35 +1389,28 @@ iso_copied = 1; } else - { fclose(fiso); - } sprintf(Line, UNZIP_FMT, opt_7z, iso_tmp, dir); if (system(Line) < 0) { - fprintf(stderr, "\nCannot unpack %s (check 7z path!)\n", iso_tmp); - if (opt_verbose) - fprintf(stderr, "Failed to execute: '%s'\n", Line); + l2l_dbg(0, "\nCannot unpack %s (check 7z path!)\n", iso_tmp); + l2l_dbg(1, "Failed to execute: '%s'\n", Line); res = 1; } else { - if (opt_verbose > 1) - fprintf(stderr, "\nUnpacking reactos.cab in %s\n", dir); + l2l_dbg(2, "\nUnpacking reactos.cab in %s\n", dir); sprintf(Line, UNZIP_FMT_CAB, opt_7z, dir, dir); if (system(Line) < 0) { - fprintf(stderr, "\nCannot unpack reactos.cab in %s\n", dir); - if (opt_verbose) - fprintf(stderr, "Failed to execute: '%s'\n", Line); + l2l_dbg(0, "\nCannot unpack reactos.cab in %s\n", dir); + l2l_dbg(1, "Failed to execute: '%s'\n", Line); res = 2; } } if (iso_copied) - { remove(iso_tmp); - } return res; } @@ -1300,78 +1424,74 @@ char *check_iso; char *check_dir; + if (opt_Revision) + revinfo.rev = getRevision(NULL, 1); check_iso = strrchr(opt_dir, '.'); + l2l_dbg(1, "Checking directory: %s\n", opt_dir); if (check_iso && PATHCMP(check_iso, ".7z") == 0) { - if (opt_verbose) - fprintf(stderr, "Uncompressing 7z image: %s\n", opt_dir); + l2l_dbg(1, "Checking 7z image: %s\n", opt_dir); - // First attempt to decompress to a .iso image + // First attempt to decompress to an .iso image strcpy(compressed_7z_path, opt_dir); if ((check_dir = strrchr(compressed_7z_path, PATH_CHAR))) - { *check_dir = '\0'; - } else strcpy(compressed_7z_path, "."); // default to current dir sprintf(Line, UNZIP_FMT_7Z, opt_7z, opt_dir, compressed_7z_path); /* This of course only works if the .7z and .iso basenames are identical - * which is normally true for our trunk builds: + * which is normally true for Reactos trunk builds: */ strcpy(check_iso, ".iso"); if (!file_exists(opt_dir) || force) { + l2l_dbg(1, "Decompressing 7z image: %s\n", opt_dir); if (system(Line) < 0) { - fprintf(stderr, "\nCannot decompress to iso image %s\n", opt_dir); - if (opt_verbose) - fprintf(stderr, "Failed to execute: '%s'\n", Line); + l2l_dbg(0, "\nCannot decompress to iso image %s\n", opt_dir); + l2l_dbg(1, "Failed to execute: '%s'\n", Line); return 2; } } else - { - if (opt_verbose > 1) - fprintf(stderr, "%s already decompressed\n", opt_dir); - } + l2l_dbg(2, "%s already decompressed\n", opt_dir); } if (check_iso && PATHCMP(check_iso, ".iso") == 0) { - if (opt_verbose) - fprintf(stderr, "Using ISO image: %s\n", opt_dir); + l2l_dbg(1, "Checking ISO image: %s\n", opt_dir); if (file_exists(opt_dir)) { - if (opt_verbose > 1) - fprintf(stderr, "ISO image exists: %s\n", opt_dir); - + l2l_dbg(2, "ISO image exists: %s\n", opt_dir); strcpy(iso_path, opt_dir); *check_iso = '\0'; sprintf(freeldr_path, "%s" PATH_STR "freeldr.ini", opt_dir); if (!file_exists(freeldr_path) || force) { - fprintf(stderr, "Unpacking %s to: %s ...", iso_path, opt_dir); + l2l_dbg(0, "Unpacking %s to: %s ...", iso_path, opt_dir); unpack_iso(opt_dir, iso_path); - fprintf(stderr, "... done\n"); + l2l_dbg(0, "... done\n"); } else - { - if (opt_verbose > 1) - fprintf(stderr, "%s already unpacked in: %s\n", iso_path, opt_dir); - } + l2l_dbg(2, "%s already unpacked in: %s\n", iso_path, opt_dir); } else { - fprintf(stderr, "ISO image not found: %s\n", opt_dir); + l2l_dbg(0, "ISO image not found: %s\n", opt_dir); return 1; } } + if (opt_Revision) + { + revinfo.buildrev = getTBRevision(opt_dir); + l2l_dbg(1,"Trunk build revision: %d\n", revinfo.buildrev); + } cache_name = malloc(MAX_PATH); tmp_name = malloc(MAX_PATH); strcpy(cache_name, opt_dir); - strcat(cache_name, PATH_STR "log2lines.cache"); + strcat(cache_name, PATH_STR CACHEFILE); strcpy(tmp_name, cache_name); strcat(tmp_name, "~"); return 0; @@ -1386,12 +1506,10 @@ int i; char *s; + strcpy(opt_dir, ""); strcpy(sources_path, ""); if ((s = getenv(SOURCES_ENV))) - { - strcpy(sources_path, s); - strcat(sources_path, PATH_STR); - } + strcpy(sources_path,s); strcpy(opt_scanned, ""); for (i = 1; i < argc; i++) @@ -1399,11 +1517,11 @@ strcat(opt_scanned, argv[i]); strcat(opt_scanned, " "); } - strcpy(opt_dir, DEF_OPT_DIR); strcpy(opt_logFile, ""); strcpy(opt_7z, CMD_7Z); memset(&summ, 0, sizeof(SUMM)); + memset(&revinfo, 0, sizeof(REVINFO)); clearLastLine(); while (-1 != (opt = getopt(argc, (char **const)argv, optchars))) @@ -1445,12 +1563,20 @@ case 'r': opt_raw++; break; + case 'R': + optCount++; + opt_Revision = malloc(LINESIZE); + i = sscanf(optarg, "%s", opt_Revision); + break; case 's': opt_stats++; break; case 'S': optCount++; - opt_Source = atoi(optarg); + i = sscanf(optarg, "%d+%d,%s", &opt_Source,&opt_SrcPlus,sources_path); + if (i == 1) + sscanf(optarg, "%*d,%s", sources_path); + l2l_dbg(3, "Sources option parse result: %d+%d,\"%s\"\n", opt_Source,opt_SrcPlus,sources_path); break; case 't': opt_twice++; @@ -1480,12 +1606,22 @@ } optCount++; } + if (sources_path[0]) + { + strcat(sources_path, PATH_STR); + } if (opt_Source) { /* need to retranslate for source info: */ opt_undo++; opt_redo++; } + if (!opt_dir[0]) + { + strcpy(opt_dir, sources_path); + strcat(opt_dir, DEF_OPT_DIR); + } + argc -= optCount; if (check_directory(opt_force)) return 3; @@ -1504,19 +1640,15 @@ // disable buffering so fflush is not needed if (!opt_buffered) { - if (opt_verbose) - fprintf(stderr, "Disabling log buffering on %s\n", opt_logFile); + l2l_dbg(1, "Disabling log buffering on %s\n", opt_logFile); setbuf(logFile, NULL); } else - { - if (opt_verbose) - fprintf(stderr, "Enabling log buffering on %s\n", opt_logFile); - } + l2l_dbg(1, "Enabling log buffering on %s\n", opt_logFile); } else { - fprintf(stderr, "Could not open logfile %s (%s)\n", opt_logFile, strerror(errno)); + l2l_dbg(0, "Could not open logfile %s (%s)\n", opt_logFile, strerror(errno)); return 2; } } @@ -1526,28 +1658,32 @@ int i = 1; const char *base = NULL; const char *offset = NULL; + char Line[LINESIZE + 1]; + while (i < argc) { + Line[0] = '\0'; offset = argv[optCount + i++]; if (isOffset(offset)) { if (base) { - if (opt_verbose > 1) - fprintf(stderr, "translating %s %s\n", base, offset); - translate_file(base, my_atoi(offset), NULL); + l2l_dbg(2, "translating %s %s\n", base, offset); + translate_file(base, my_atoi(offset), Line); + printf("%s\n", Line); + reportRevision(stdout); reportSource(stdout); } else { - fprintf(stderr, " expected\n"); + l2l_dbg(0, " expected\n"); res = 3; break; } } else { - // Must be exefile + // Not an offset so must be an exefile: base = offset; } }