home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / sherlock.zip / SRCDISP.C < prev    next >
C/C++ Source or Header  |  1994-06-29  |  8KB  |  355 lines

  1. /*
  2. **  Sherlock - Copyright 1992, 1993, 1994
  3. **    Harfmann Software
  4. **    Compuserve: 73147,213
  5. **    All rights reserved
  6. */
  7. /*
  8. ** Display the source for the given source file and line number.
  9. */
  10. #include    <stdio.h>
  11. #include    <stdlib.h>
  12. #include    <ctype.h>
  13. #include    <string.h>
  14. #include    <sys\stat.h>
  15.  
  16. #define     INCL_DOSPROCESS
  17. #include    <os2.h>
  18. #include    "debug.h"
  19.  
  20. #include    "Debugger.h"
  21. #include    "SrcInter.h"
  22. #include    "Source.h"
  23. #include    "SrcDisp.h"
  24.  
  25. typedef struct {
  26.     char   *basePath;
  27.     char   *lastSource;
  28.     int     lastLine;
  29.     ULONG   lastAddr;
  30. } View;
  31.  
  32. static char    drive[_MAX_DRIVE];
  33. static char    dir[_MAX_DIR];
  34. static char    fname[_MAX_FNAME];
  35. static char    ext[_MAX_EXT];
  36. static int     ShouldDumpSource = 1;
  37. static int     ShouldDumpAsm = 0;
  38.  
  39. /*
  40. ** Set the view into the source.
  41. */
  42. int CommandSource(char **ptrs)
  43. {
  44.     if(ptrs[1][1] == '+') {
  45.     ShouldDumpSource = 1;
  46.     ShouldDumpAsm     = 0;
  47.     return -1;
  48.     }
  49.  
  50.     if(ptrs[1][1] == '&') {
  51.     ShouldDumpSource = 1;
  52.     ShouldDumpAsm     = 1;
  53.     return -1;
  54.     }
  55.  
  56.     if(ptrs[1][1] == '-') {
  57.     ShouldDumpSource = 0;
  58.     ShouldDumpAsm     = 1;
  59.     return -1;
  60.     }
  61.  
  62.     fprintf(logFile, "Source command error\n");
  63.     return -1;
  64. }
  65.  
  66. /*
  67. ** View the source for the lines specified.
  68. */
  69. int CommandView(char **ptrs)
  70. {
  71. DebugModule    *module;
  72. char           *srcEnd;
  73. ULONG        addr;
  74. ULONG        lineNum;
  75. char        funcName[MAX_FUNCNAME];
  76. char        sourceName[CCHMAXPATH];
  77.  
  78.     /*
  79.     ** Get the common data.
  80.     */
  81.     module = FindModule(debugBuffer.MTE, NULL);
  82.     FindSource(module, Linearize(debugBuffer.EIP, debugBuffer.CS),
  83.            funcName, sourceName, &lineNum);
  84.  
  85.     /*
  86.     ** View the next lines to be displayed.
  87.     */
  88.     if(ptrs[2] == NULL) {
  89.     DisplaySource(module, sourceName, GetLastLine(module) + 5);
  90.     return -1;
  91.     }
  92.  
  93.     /*
  94.     ** View a line.
  95.     */
  96.     if(ptrs[2][0] == '.') {
  97.  
  98.     /*
  99.     ** Find the line number or the file name/line number
  100.     */
  101.     if(isdigit(ptrs[2][1])) {
  102.         lineNum = atol(&ptrs[2][1]);
  103.     } else {
  104.         strcpy(sourceName, &ptrs[2][1]);
  105.         *strrchr(sourceName, ':') = 0;
  106.         lineNum = atol(strrchr(ptrs[2], ':') + 1);
  107.     }
  108.     DisplaySource(module, sourceName, lineNum);
  109.     return -1;
  110.     }
  111.  
  112.     /*
  113.     ** Get a view at a given offset.
  114.     */
  115.     if(isxdigit(ptrs[2][0])) {
  116.     /*
  117.     ** Find the module associated with the address specified.
  118.     */
  119.     debugBuffer.Addr = addr = StrToAddr(ptrs[2], TOADDR_CODE);
  120.     DispatchCommand(DBG_C_AddrToObject);
  121.  
  122.     /*
  123.     ** Find the module/source associated with the information given.
  124.     */
  125.     module = FindModule(debugBuffer.MTE, NULL);
  126.     FindSource(NULL, addr, funcName, sourceName, &lineNum);
  127.     DisplaySource(module, sourceName, lineNum);
  128.     return -1;
  129.     }
  130.  
  131.     /*
  132.     ** ERROR!
  133.     */
  134.     fprintf(logFile, "Invalid syntax\n");
  135.     return -1;
  136. }
  137.  
  138. /*
  139. ** View the assembler for the address/line specified.
  140. */
  141. int CommandUnassemble(char **ptrs)
  142. {
  143. DebugModule    *module;
  144. View           *viewData;
  145. char           *srcEnd;
  146. ULONG        addr;
  147. int        lineNum;
  148. int        is32Bit;
  149. char        sourceName[CCHMAXPATH];
  150.  
  151.     /*
  152.     ** Get the common data.
  153.     */
  154.     module   = FindModule(debugBuffer.MTE, NULL);
  155.     viewData = (View *) module->ViewData;
  156.     if(viewData == NULL) {
  157.     viewData = module->ViewData = calloc(sizeof(View), 1);
  158.     viewData->lastSource = strdup("");
  159.     viewData->basePath   = strdup("");
  160.     }
  161.     is32Bit  = (debugBuffer.CSAtr & 0x80) != 0;
  162.     addr     = Linearize(debugBuffer.EIP, debugBuffer.CS);
  163.  
  164.     /*
  165.     ** View the next lines to be displayed.
  166.     */
  167.     if(ptrs[2] == NULL) {
  168.         DumpAsm(viewData->lastAddr, 0x20, is32Bit);
  169.     viewData->lastAddr = addr + 0x20;
  170.     return -1;
  171.     }
  172.  
  173.     /*
  174.     ** View a source line.
  175.     */
  176.     if(ptrs[2][0] == '.') {
  177.  
  178.     /*
  179.     ** Find the line number or the file name/line number
  180.     */
  181.     if(isdigit(ptrs[2][1])) {
  182.         lineNum = atol(&ptrs[2][1]);
  183.         if(viewData->lastSource == NULL) {
  184.         fprintf(logFile, "No source yet displayed\n");
  185.         return -1;
  186.         }
  187.         strcpy(sourceName, viewData->lastSource);
  188.     } else {
  189.         strcpy(sourceName, &ptrs[2][1]);
  190.         *strrchr(sourceName, ':') = 0;
  191.         lineNum = atol(strrchr(ptrs[2], ':') + 1);
  192.     }
  193.     addr = FindSourceLine(module, lineNum, sourceName);
  194.     DumpAsm(addr, 0x20, is32Bit);
  195.     viewData->lastAddr = addr + 0x20;
  196.     return -1;
  197.     }
  198.  
  199.     /*
  200.     ** Get a view at a given offset.
  201.     */
  202.     if(isxdigit(ptrs[2][0])) {
  203.     addr = StrToAddr(ptrs[2], TOADDR_CODE);
  204.     DumpAsm(addr, 0x20, is32Bit);
  205.     viewData->lastAddr = addr + 0x20;
  206.     return -1;
  207.     }
  208.  
  209.     /*
  210.     ** ERROR!
  211.     */
  212.     fprintf(logFile, "Invalid syntax\n");
  213.     return -1;
  214. }
  215.  
  216. /*
  217. ** Display the source file and line number.
  218. */
  219. int DisplaySource(DebugModule *module, char *sourceName, int lineNum)
  220. {
  221. int    i, lastChar, is32Bit;
  222. int    curLine;
  223. FILE   *file = NULL;
  224. View   *viewData = (View *) module->ViewData;
  225. ULONG    addr, addr2;
  226. char    buff[CCHMAXPATH];
  227. char    dummy[CCHMAXPATH];
  228.  
  229.     /*
  230.     ** Find out whether this is a 32 bit segment.
  231.     */
  232.     DispatchCommand(DBG_C_ReadReg);
  233.     is32Bit = (debugBuffer.CSAtr & 0x80) != 0;
  234.  
  235.     /*
  236.     ** If the view data does not exist, create and initialize it.
  237.     */
  238.     if(viewData == NULL) {
  239.     viewData = module->ViewData = calloc(sizeof(View), 1);
  240.     viewData->lastSource = strdup("");
  241.     viewData->basePath   = strdup("");
  242.     }
  243.  
  244.     /*
  245.     ** Find and open the source file.
  246.     */
  247.     if(strlen(sourceName) > 0) {
  248.     strcpy(buff, sourceName);
  249.     _splitpath(sourceName, drive, dir, fname, ext);
  250.     _splitpath(viewData->basePath, drive, dir, dummy, dummy);
  251.     _makepath(buff, drive, dir, fname, ext);
  252.     while((file = fopen(buff, "r")) == NULL) {
  253. #ifdef SHERLOCK
  254.         buff[0] = 0;
  255. #else
  256.         fprintf(logFile, "Please enter path for %s\n", sourceName);
  257.         fgets(buff, sizeof(buff), stdin);
  258. #endif
  259.         while((strlen(buff) > 0) && isspace(*buff))
  260.         buff[strlen(buff) - 1] = 0;
  261.         if(strlen(buff) == 0)
  262.         return 0;
  263.  
  264.         lastChar = strlen(buff) - 1;
  265.         while(isspace(buff[lastChar])) {
  266.         buff[lastChar] = 0;
  267.         lastChar--;
  268.         }
  269.         if((buff[lastChar] != '\\') && (buff[lastChar] != '/'))
  270.         strcat(buff, "/");
  271.         _splitpath(buff, drive, dir, dummy, dummy);
  272.         _makepath(buff, drive, dir, fname, ext);
  273.     }
  274.     }
  275.  
  276.     /*
  277.     ** Free/show the last source viewed.
  278.     */
  279.     if(viewData->lastSource)
  280.     free(viewData->lastSource);
  281.     viewData->lastSource = strdup(buff);
  282.  
  283.     /*
  284.     ** Free the previous path spec.
  285.     */
  286.     if(viewData->basePath)
  287.     free(viewData->basePath);
  288.     _splitpath(buff, drive, dir, fname, ext);
  289.     _makepath(buff, drive, dir, "", "");
  290.     viewData->basePath = strdup(buff);
  291.  
  292.     /*
  293.     ** Go to just before the line specific.
  294.     */
  295.     if(file) {
  296.     curLine = 0;
  297.     for(curLine=1; curLine < lineNum - 5; curLine++) {
  298.         fgets(buff, sizeof(buff), file);
  299.     }
  300.     }
  301.  
  302.     /*
  303.     ** Now, display the source.
  304.     */
  305.     if(file) {
  306.     for(i=0; i<10; i++, curLine++) {
  307.         if(file)
  308.         if(fgets(buff, sizeof(buff), file) == NULL)
  309.             break;
  310.         if(ShouldDumpSource) {
  311.         if(curLine == lineNum)
  312.             fprintf(logFile, "*%5d: %s", curLine, buff);
  313.         else
  314.             fprintf(logFile, " %5d: %s", curLine, buff);
  315.         }
  316.         if((addr = FindSourceLine(module, curLine, sourceName)) != 0) {
  317.         int    j;
  318.  
  319.         /*
  320.         ** Find the next line.
  321.         */
  322.         for(j=1; j < 10; j++) {
  323.             if((addr2=FindSourceLine(module,curLine+j,sourceName))!=0)
  324.             break;
  325.         }
  326.         }
  327.         if(addr2 == 0)
  328.         addr2 = addr + 0x10;
  329.         if(ShouldDumpAsm)
  330.         DumpAsm(addr, addr2-addr, is32Bit);
  331.     }
  332.     } else {
  333.     addr = Linearize(debugBuffer.EIP, debugBuffer.CS);
  334.     DumpAsm(addr, 0x20, is32Bit);
  335.     addr2 = addr + 0x20;
  336.     }
  337.     viewData->lastLine = curLine - 1;
  338.     viewData->lastAddr = addr2;
  339.     if(file)
  340.     fclose(file);
  341.     return 1;
  342. }
  343.  
  344. /*
  345. ** Answer the last line displayed for the module.
  346. */
  347. int GetLastLine(DebugModule *module)
  348. {
  349. View   *viewData = (View *) module->ViewData;
  350.  
  351.     if(viewData == NULL)
  352.     return -1;
  353.     return viewData->lastLine;
  354. }
  355.