ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

log2lines.c
Go to the documentation of this file.
00001 /*
00002  * ReactOS log2lines
00003  * Written by Jan Roeloffzen
00004  *
00005  * - Initialization, translation and main loop
00006  */
00007 
00008 #include <errno.h>
00009 #include <stdio.h>
00010 #include <string.h>
00011 #include <stdlib.h>
00012 
00013 #include "util.h"
00014 #include "version.h"
00015 #include "compat.h"
00016 #include "options.h"
00017 #include "image.h"
00018 #include "cache.h"
00019 #include "log2lines.h"
00020 #include "help.h"
00021 #include "cmd.h"
00022 #include "match.h"
00023 
00024 
00025 static FILE *dbgIn          = NULL;
00026 static FILE *dbgOut         = NULL;
00027 static FILE *conIn          = NULL;
00028 static FILE *conOut         = NULL;
00029 static const char *kdbg_prompt = KDBG_PROMPT;
00030 static const char *kdbg_cont   = KDBG_CONT;
00031 
00032 LIST sources;
00033 LINEINFO lastLine;
00034 FILE *logFile        = NULL;
00035 LIST cache;
00036 SUMM summ;
00037 REVINFO revinfo;
00038 
00039 
00040 static void
00041 clearLastLine(void)
00042 {
00043     memset(&lastLine, 0, sizeof(LINEINFO));
00044 }
00045 
00046 static void
00047 log_file(FILE *outFile, char *fileName, int line)
00048 {
00049     int i = 0, min = 0, max = 0;
00050     char s[LINESIZE];
00051     FILE *src;
00052 
00053     strcpy(s, opt_SourcesPath);
00054     strcat(s, fileName);
00055 
00056     max = line + opt_SrcPlus;
00057     if ((src = fopen(s, "r")))
00058     {
00059         min = line - opt_Source;
00060         min = (min < 0) ? 0 : min;
00061         while (i < max && fgets(s, LINESIZE, src))
00062         {
00063             if (i >= min)
00064             {
00065                 if (i == line)
00066                     log(outFile, "| ----\n");
00067                 log(outFile, "| %4.4d  %s", i + 1, s);
00068             }
00069             i++;
00070         }
00071         fclose(src);
00072         if ( i < min )
00073             log(outFile, "| S--- source has only %d lines! (check source/revision)\n", i);
00074     }
00075     else
00076         l2l_dbg(1, "Can't open: %s (check " SOURCES_ENV ")\n", s);
00077 }
00078 
00079 static void
00080 logSource(FILE *outFile)
00081 {
00082     log_file(outFile, lastLine.file1, lastLine.nr1);
00083     if (lastLine.nr2)
00084     {
00085         log(outFile, "| ---- [%u] ----\n", lastLine.nr2);
00086         log_file(outFile, lastLine.file2, lastLine.nr2);
00087     }
00088 }
00089 
00090 static void
00091 reportSource(FILE *outFile)
00092 {
00093     if (!opt_Source)
00094         return;
00095     if (lastLine.valid)
00096         logSource(outFile);
00097 }
00098 
00099 static void
00100 report(FILE *outFile)
00101 {
00102     reportRevision(outFile);
00103     reportSource(outFile);
00104     clearLastLine();
00105 }
00106 
00107 
00108 static int
00109 print_offset(void *data, size_t offset, char *toString)
00110 {
00111     PSYMBOLFILE_HEADER RosSymHeader = (PSYMBOLFILE_HEADER)data;
00112     PROSSYM_ENTRY e = NULL;
00113     PROSSYM_ENTRY e2 = NULL;
00114     int bFileOffsetChanged = 0;
00115     char fmt[LINESIZE];
00116     char *Strings = (char *)data + RosSymHeader->StringsOffset;
00117 
00118     fmt[0] = '\0';
00119     e = find_offset(data, offset);
00120     if (opt_twice)
00121     {
00122         e2 = find_offset(data, offset - 1);
00123 
00124         if (e == e2)
00125             e2 = NULL;
00126         else
00127             summ.diff++;
00128 
00129         if (opt_Twice && e2)
00130         {
00131             e = e2;
00132             e2 = NULL;
00133             /* replaced (transparantly), but updated stats */
00134         }
00135     }
00136     if (e || e2)
00137     {
00138         strcpy(lastLine.file1, &Strings[e->FileOffset]);
00139         strcpy(lastLine.func1, &Strings[e->FunctionOffset]);
00140         lastLine.nr1 = e->SourceLine;
00141         sources_entry_create(&sources, lastLine.file1, SVN_PREFIX);
00142         lastLine.valid = 1;
00143         if (e2)
00144         {
00145             strcpy(lastLine.file2, &Strings[e2->FileOffset]);
00146             strcpy(lastLine.func2, &Strings[e2->FunctionOffset]);
00147             lastLine.nr2 = e2->SourceLine;
00148             sources_entry_create(&sources, lastLine.file2, SVN_PREFIX);
00149             bFileOffsetChanged = e->FileOffset != e2->FileOffset;
00150             if (e->FileOffset != e2->FileOffset || e->FunctionOffset != e2->FunctionOffset)
00151                 summ.majordiff++;
00152 
00153             /*
00154              * - "%.0s" displays nothing, but processes argument
00155              * - bFileOffsetChanged implies always display 2nd SourceLine even if the same
00156              * - also for FunctionOffset
00157              */
00158             strcat(fmt, "%s");
00159             if (bFileOffsetChanged)
00160                 strcat(fmt, "[%s]");
00161             else
00162                 strcat(fmt, "%.0s");
00163 
00164             strcat(fmt, ":%u");
00165             if (e->SourceLine != e2->SourceLine || bFileOffsetChanged)
00166                 strcat(fmt, "[%u]");
00167             else
00168                 strcat(fmt, "%.0u");
00169 
00170             strcat(fmt, " (%s");
00171             if (e->FunctionOffset != e2->FunctionOffset || bFileOffsetChanged)
00172                 strcat(fmt, "[%s])");
00173             else
00174                 strcat(fmt, "%.0s)");
00175 
00176             if (toString)
00177             {   // put in toString if provided
00178                 snprintf(toString, LINESIZE, fmt,
00179                     &Strings[e->FileOffset],
00180                     &Strings[e2->FileOffset],
00181                     (unsigned int)e->SourceLine,
00182                     (unsigned int)e2->SourceLine,
00183                     &Strings[e->FunctionOffset],
00184                     &Strings[e2->FunctionOffset]);
00185             }
00186             else
00187             {
00188                 strcat(fmt, "\n");
00189                 printf(fmt,
00190                     &Strings[e->FileOffset],
00191                     &Strings[e2->FileOffset],
00192                     (unsigned int)e->SourceLine,
00193                     (unsigned int)e2->SourceLine,
00194                     &Strings[e->FunctionOffset],
00195                     &Strings[e2->FunctionOffset]);
00196             }
00197         }
00198         else
00199         {
00200             if (toString)
00201             {   // put in toString if provided
00202                 snprintf(toString, LINESIZE, "%s:%u (%s)",
00203                     &Strings[e->FileOffset],
00204                     (unsigned int)e->SourceLine,
00205                     &Strings[e->FunctionOffset]);
00206             }
00207             else
00208             {
00209                 printf("%s:%u (%s)\n",
00210                     &Strings[e->FileOffset],
00211                     (unsigned int)e->SourceLine,
00212                     &Strings[e->FunctionOffset]);
00213             }
00214         }
00215         return 0;
00216     }
00217     return 1;
00218 }
00219 
00220 static int
00221 process_data(const void *FileData, size_t offset, char *toString)
00222 {
00223     int res;
00224 
00225     PIMAGE_SECTION_HEADER PERosSymSectionHeader = get_sectionheader((char *)FileData);
00226     if (!PERosSymSectionHeader)
00227         return 2;
00228 
00229     res = print_offset((char *)FileData + PERosSymSectionHeader->PointerToRawData, offset, toString);
00230     if (res)
00231     {
00232         if (toString)
00233             sprintf(toString, "??:0");
00234         else
00235             printf("??:0");
00236         l2l_dbg(1, "Offset not found: %x\n", (unsigned int)offset);
00237         summ.offset_errors++;
00238     }
00239 
00240     return res;
00241 }
00242 
00243 static int
00244 process_file(const char *file_name, size_t offset, char *toString)
00245 {
00246     void *FileData;
00247     size_t FileSize;
00248     int res = 1;
00249 
00250     FileData = load_file(file_name, &FileSize);
00251     if (!FileData)
00252     {
00253         l2l_dbg(0, "An error occured loading '%s'\n", file_name);
00254     }
00255     else
00256     {
00257         res = process_data(FileData, offset, toString);
00258         free(FileData);
00259     }
00260     return res;
00261 }
00262 
00263 static int
00264 translate_file(const char *cpath, size_t offset, char *toString)
00265 {
00266     size_t base = 0;
00267     LIST_MEMBER *pentry = NULL;
00268     int res = 0;
00269     char *path, *dpath;
00270 
00271     dpath = path = convert_path(cpath);
00272     if (!path)
00273         return 1;
00274 
00275     // The path could be absolute:
00276     if (get_ImageBase(path, &base))
00277     {
00278         pentry = entry_lookup(&cache, path);
00279         if (pentry)
00280         {
00281             path = pentry->path;
00282             base = pentry->ImageBase;
00283             if (base == INVALID_BASE)
00284             {
00285                 l2l_dbg(1, "No, or invalid base address: %s\n", path);
00286                 res = 2;
00287             }
00288         }
00289         else
00290         {
00291             l2l_dbg(1, "Not found in cache: %s\n", path);
00292             res = 3;
00293         }
00294     }
00295 
00296     if (!res)
00297     {
00298         res = process_file(path, offset, toString);
00299     }
00300 
00301     free(dpath);
00302     return res;
00303 }
00304 
00305 static void
00306 translate_char(int c, FILE *outFile)
00307 {
00308     fputc(c, outFile);
00309     if (logFile)
00310         fputc(c, logFile);
00311 }
00312 
00313 static char *
00314 remove_mark(char *Line)
00315 {
00316     if (Line[1] == ' ' && Line[2] == '<')
00317         if (Line[0] == '*' || Line[0] == '?')
00318             return Line + 2;
00319     return Line;
00320 }
00321 
00322 static void
00323 translate_line(FILE *outFile, char *Line, char *path, char *LineOut)
00324 {
00325     size_t offset;
00326     int cnt, res;
00327     char *sep, *tail, *mark, *s;
00328     unsigned char ch;
00329 
00330     if (!*Line)
00331         return;
00332 
00333     res = 1;
00334     mark = "";
00335     s = remove_mark(Line);
00336     if (opt_undo)
00337     {
00338         /* Strip all lines added by this tool: */
00339         char buf[NAMESIZE];
00340         if (sscanf(s, "| %s", buf) == 1)
00341             if (buf[0] == '0' || strcmp(buf, "----") == 0 || strcmp(buf, "L2L-") == 0 || strcmp(buf, "S---") == 0 || strcmp(buf, "R---") == 0 || atoi(buf))
00342                 res = 0;
00343     }
00344 
00345     sep = strchr(s, ':');
00346     if (sep)
00347     {
00348         *sep = ' ';
00349         cnt = sscanf(s, "<%s %x%c", path, (unsigned int *)(&offset), &ch);
00350         if (opt_undo)
00351         {
00352             if (cnt == 3 && ch == ' ')
00353             {
00354                 tail = strchr(s, '>');
00355                 tail = tail ? tail - 1 : tail;
00356                 if (tail && tail[0] == ')' && tail[1] == '>')
00357                 {
00358                     res = 0;
00359                     tail += 2;
00360                     mark = opt_mark ? "* " : "";
00361                     if (opt_redo && !(res = translate_file(path, offset, LineOut)))
00362                     {
00363                         log(outFile, "%s<%s:%x (%s)>%s", mark, path, (unsigned int)offset, LineOut, tail);
00364                         summ.redo++;
00365                     }
00366                     else
00367                     {
00368                         log(outFile, "%s<%s:%x>%s", mark, path, (unsigned int)offset, tail);
00369                         summ.undo++;
00370                     }
00371                 }
00372                 else
00373                 {
00374                     mark = opt_Mark ? "? " : "";
00375                     summ.skipped++;
00376                 }
00377                 summ.total++;
00378             }
00379         }
00380 
00381         if (!opt_undo || opt_redo)
00382         {
00383             if (cnt == 3 && ch == '>')
00384             {
00385                 tail = strchr(s, '>') + 1;
00386                 if (!(res = translate_file(path, offset, LineOut)))
00387                 {
00388                     mark = opt_mark ? "* " : "";
00389                     log(outFile, "%s<%s:%x (%s)>%s", mark, path, (unsigned int)offset, LineOut, tail);
00390                     summ.translated++;
00391                 }
00392                 else
00393                 {
00394                     mark = opt_Mark ? "? " : "";
00395                     summ.skipped++;
00396                 }
00397                 summ.total++;
00398             }
00399         }
00400     }
00401     if (res)
00402     {
00403         if (sep)
00404             *sep = ':';  // restore because not translated
00405         log(outFile, "%s%s", mark, s);
00406     }
00407     memset(Line, '\0', LINESIZE);  // flushed
00408 }
00409 
00410 static int
00411 translate_files(FILE *inFile, FILE *outFile)
00412 {
00413     char *Line = malloc(LINESIZE + 1);
00414     char *path = malloc(LINESIZE + 1);
00415     char *LineOut = malloc(LINESIZE + 1);
00416     int c;
00417     unsigned char ch;
00418     int i = 0;
00419     const char *pc    = kdbg_cont;
00420     const char *p     = kdbg_prompt;
00421     const char *p_eos = p + sizeof(KDBG_PROMPT) - 1; //end of string pos
00422 
00423     if (Line && path && LineOut)
00424     {
00425         memset(Line, '\0', LINESIZE + 1);
00426         if (opt_console)
00427         {
00428             while ((c = fgetc(inFile)) != EOF)
00429             {
00430                 if (opt_quit)break;
00431 
00432                 ch = (unsigned char)c;
00433                 if (!opt_raw)
00434                 {
00435                     switch (ch)
00436                     {
00437                     case '\n':
00438                         if ( strncmp(Line, KDBG_DISCARD, sizeof(KDBG_DISCARD)-1) == 0 )
00439                         {
00440                             memset(Line, '\0', LINESIZE);  // flushed
00441                         }
00442                         else
00443                         {
00444                             Line[1] = handle_escape_cmd(outFile, Line, path, LineOut);
00445                             if (Line[1] != KDBG_ESC_CHAR)
00446                             {
00447                                 if (p == p_eos)
00448                                 {
00449                                     // kdbg prompt, so already echoed char by char
00450                                     memset(Line, '\0', LINESIZE);
00451                                     translate_char(c, outFile);
00452                                 }
00453                                 else
00454                                 {
00455                                     if (match_line(outFile, Line))
00456                                     {
00457                                         translate_line(outFile, Line, path, LineOut);
00458                                         translate_char(c, outFile);
00459                                         report(outFile);
00460                                     }
00461                                 }
00462                             }
00463                         }
00464                         i = 0;
00465                         p  = kdbg_prompt;
00466                         pc = kdbg_cont;
00467                         break;
00468                     case '<':
00469                         i = 0;
00470                         Line[i++] = ch;
00471                         break;
00472                     case '>':
00473                         if (ch == *p)
00474                         {
00475                             p = p_eos;
00476                             translate_line(outFile, Line, path, LineOut);
00477                         }
00478 
00479                         if (p != p_eos)
00480                         {
00481                             if (i < LINESIZE)
00482                             {
00483                                 Line[i++] = ch;
00484                                 translate_line(outFile, Line, path, LineOut);
00485                             }
00486                             else
00487                             {
00488                                 translate_line(outFile, Line, path, LineOut);
00489                                 translate_char(c, outFile);
00490                             }
00491                         }
00492                         else
00493                             translate_char(c, outFile);
00494                         i = 0;
00495                         break;
00496                     default:
00497                         if (ch == *p)p++;
00498                         if (ch == *pc)pc++;
00499                         if (i < LINESIZE)
00500                         {
00501                             Line[i++] = ch;
00502                             if (p == p_eos)
00503                             {
00504                                 translate_char(c, outFile);
00505                             }
00506                             else if (!*pc)
00507                             {
00508                                 translate_line(outFile, Line, path, LineOut);
00509                                 i = 0;
00510                             }
00511                         }
00512                         else
00513                         {
00514                             translate_line(outFile, Line, path, LineOut);
00515                             translate_char(c, outFile);
00516                             i = 0;
00517                         }
00518                     }
00519                 }
00520                 else
00521                     translate_char(c, outFile);
00522             }
00523         }
00524         else
00525         {   // Line by line, slightly faster but less interactive
00526             while (fgets(Line, LINESIZE, inFile) != NULL)
00527             {
00528                 if (opt_quit)break;
00529 
00530                 if (!opt_raw)
00531                 {
00532                     translate_line(outFile, Line, path, LineOut);
00533                     report(outFile);
00534                 }
00535                 else
00536                     log(outFile, "%s", Line);
00537             }
00538         }
00539     }
00540 
00541     if (opt_Revision && (strstr(opt_Revision, "regscan") == opt_Revision))
00542     {
00543         char *s = strchr(opt_Revision, ',');
00544         if (s)
00545         {
00546             *s++ = '\0';
00547             revinfo.range = atoi(s);
00548         }
00549         regscan(outFile);
00550     }
00551 
00552     if (opt_stats)
00553     {
00554         stat_print(outFile, &summ);
00555         if (logFile)
00556             stat_print(logFile, &summ);
00557     }
00558     free(LineOut);
00559     free(Line);
00560     free(path);
00561     return 0;
00562 }
00563 
00564 
00565 int
00566 main(int argc, const char **argv)
00567 {
00568     int res = 0;
00569     int optCount = 0;
00570 
00571     dbgIn = stdin;
00572     conOut = stdout;
00573     (void)conIn;
00574     (void)dbgOut;
00575 
00576     memset(&cache, 0, sizeof(LIST));
00577     memset(&sources, 0, sizeof(LIST));
00578     stat_clear(&summ);
00579     memset(&revinfo, 0, sizeof(REVINFO));
00580     clearLastLine();
00581 
00582     optionInit(argc, argv);
00583     optCount = optionParse(argc, argv);
00584     if (optCount < 0)
00585     {
00586         return optCount;
00587     }
00588 
00589     argc -= optCount;
00590 
00591     if (opt_Revision && (strcmp(opt_Revision, "update") == 0))
00592     {
00593         res = updateSvnlog();
00594         return res;
00595     }
00596 
00597     if (check_directory(opt_force))
00598         return 3;
00599 
00600     create_cache(opt_force, 0);
00601     if (opt_exit)
00602         return 0;
00603 
00604     read_cache();
00605     l2l_dbg(4, "Cache read complete\n");
00606 
00607     if (set_LogFile(&logFile))
00608         return 2;
00609     l2l_dbg(4, "opt_logFile processed\n");
00610 
00611     if (opt_Pipe)
00612     {
00613         l2l_dbg(3, "Command line: \"%s\"\n",opt_Pipe);
00614 
00615         if (!(dbgIn = POPEN(opt_Pipe, "r")))
00616         {
00617             dbgIn = stdin; //restore
00618             l2l_dbg(0, "Could not popen '%s' (%s)\n", opt_Pipe, strerror(errno));
00619             free(opt_Pipe); opt_Pipe = NULL;
00620         }
00621     }
00622     l2l_dbg(4, "opt_Pipe processed\n");
00623 
00624     if (argc > 1)
00625     {   // translate {<exefile> <offset>}
00626         int i = 1;
00627         const char *exefile = NULL;
00628         const char *offset = NULL;
00629         char Line[LINESIZE + 1];
00630 
00631         while (i < argc)
00632         {
00633             Line[0] = '\0';
00634             offset = argv[optCount + i++];
00635             if (isOffset(offset))
00636             {
00637                 if (exefile)
00638                 {
00639                     l2l_dbg(2, "translating %s %s\n", exefile, offset);
00640                     translate_file(exefile, my_atoi(offset), Line);
00641                     printf("%s\n", Line);
00642                     report(conOut);
00643                 }
00644                 else
00645                 {
00646                     l2l_dbg(0, "<exefile> expected\n");
00647                     res = 3;
00648                     break;
00649                 }
00650             }
00651             else
00652             {
00653                 // Not an offset so must be an exefile:
00654                 exefile = offset;
00655             }
00656         }
00657     }
00658     else
00659     {   // translate logging from stdin
00660         translate_files(dbgIn, conOut);
00661     }
00662 
00663     if (logFile)
00664         fclose(logFile);
00665 
00666     if (opt_Pipe)
00667         PCLOSE(dbgIn);
00668 
00669     return res;
00670 }
00671 
00672 /* EOF */

Generated on Thu May 24 2012 04:38:05 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.