home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / dos / grafik / cgazv5n3 / apps.c next >
Encoding:
C/C++ Source or Header  |  1991-02-25  |  10.0 KB  |  291 lines

  1. /*******  Listing 5  ***************************  APPS.C  ************
  2. *  apps.c -- Applications using OBJECT CODE EXPLORER
  3. *  Author:   Thomas E. Siering, 1991. Copyruight notice in Listing 1
  4. *  Compiler: Microsoft C 6.0, Turbo C++ 1.0
  5. *  Compile time switches:
  6. *    PRN - listings use only characters avaialable on printers
  7. *    CON - listings use only characters available on the console
  8. *  Links with: svc.c and ox.c. This module contains the main driver
  9. *  Usage: apps file.obj
  10. *  Generates file.dmp and file.anl, showing the contents of file.obj
  11. ***********************************************************************/
  12. #include <stdio.h>
  13. #include <string.h>
  14. #include <stdlib.h>
  15. #include <ctype.h>
  16. #include "ox.h"
  17.  
  18.  
  19. /* Define the following DOS system constants for non MS C compilers */
  20. #ifndef _MAX_PATH
  21. #define _MAX_PATH    260    /* max. length of full pathname */
  22. #endif
  23. #ifndef _MAX_FNAME
  24. #define _MAX_FNAME    256    /* max. length of file name component */
  25. #endif
  26.  
  27. #if defined(__TURBOC__)
  28. #define SplitPath fnsplit          /* Turbo C */
  29. #else
  30. #define SplitPath _splitpath       /* MS C    */
  31. #endif
  32.  
  33.  
  34. PUBLIC FILE *AnalysisFH;
  35. PUBLIC char *obj;
  36.  
  37. PRIVATE char ProgramName[] = { "ox" };
  38.  
  39.  
  40. PRIVATE void Init(int argc, char *argv[], char ObjFN[], char **ws,
  41.         long *ObjSize);
  42. PRIVATE void Dump(char *ObjP, int FileLength, char *ObjName);
  43. PRIVATE void Analyze(char Obj[], long ObjLength, char *ObjName);
  44.  
  45.  
  46. PUBLIC void main(int argc, char *argv[]);
  47.  
  48. void main(int argc, char *argv[])
  49. {
  50.     long FileLength;
  51.     char ObjFN[_MAX_FNAME];
  52.  
  53.     Init(argc, argv, ObjFN, &obj, &FileLength);
  54.     Dump(obj, (int) FileLength, ObjFN);
  55.     if (argv[2][1] != 'd' && argv[2][1] != 'D')
  56.         Analyze(obj, FileLength, ObjFN);
  57.     free(obj);
  58. }
  59.  
  60. /*----------------------------------------------
  61. *   Init  --  Initialize various mundane things
  62. *--------------------------------------------**/
  63. PRIVATE void Init(int argc, char *argv[], char ObjFNRoot[], char **ws,
  64.         long *ObjSize)
  65. {
  66.     char ObjFileName[_MAX_PATH];
  67.     char Dummy[_MAX_PATH];
  68.     char FileExt[5];        /* allow for leading . and trailing \0 */
  69.  
  70.     if (argc < 2) {
  71.         fprintf(stderr, "CALL: %s FN.OBJ [options]\n", ProgramName);
  72.         fprintf(stderr, "Options: /d -- Dump only\n");
  73.         exit(-1);
  74.     }
  75.  
  76.     strcpy(ObjFileName, argv[1]);
  77.     strcpy(ObjFNRoot, argv[1]);   /* for remainder of program, w/out ext. */
  78.  
  79.     /* Did the user enter an extension w/ file name? */
  80.     SplitPath(ObjFileName, Dummy, Dummy, Dummy, FileExt);
  81.     if (FileExt[0] == '.' && FileExt[1] != '\0')  /* has an extension */
  82.         ObjFNRoot[strrchr(ObjFNRoot, '.') - ObjFNRoot] = '\0';
  83.     else
  84.         strcat(ObjFileName, ".OBJ\0");  /* OBJ ext needed to open file */
  85.  
  86.     InstObjExp(ObjFileName, ws, ObjSize);
  87. }
  88.  
  89. #define  PRN           /* for output ctl: enable PRN -OR- CON */
  90. /* #define  CON */
  91. #ifdef PRN
  92.    #define CHKCHAR  !isprint
  93. #else
  94.    #define CHKCHAR  iscntrl
  95. #endif
  96.  
  97. #define  MAXLN    16
  98. #define  ASCIICOL 62
  99.  
  100. /*-----------------------------------------
  101. *   Dump --  formatted dump of OBJ records
  102. *----------------------------------------*/
  103. PRIVATE void Dump(char *ObjP, int  FileLength, char *ObjName)
  104. {
  105.     FILE *DumpFH;
  106.     int  LocCtr = 0;
  107.     char ObjRecName[OMFNAMELENGTH];
  108.     char DumpFN[_MAX_PATH];
  109.     int  RecLength;
  110.     int  PrintLength;
  111.  
  112.     strcpy(DumpFN, ObjName);
  113.     strcat(DumpFN, ".DMP");
  114.  
  115.     if ((DumpFH = fopen(DumpFN, "w")) == NULL) {
  116.         fprintf(stderr, "\aCould Not Open File %s.\n", DumpFN);
  117.         exit(0xFF);
  118.     }
  119.  
  120.     while (FileLength) {
  121.         RecLength = *((int *) (ObjP + 1)) + 3;
  122.         if (GetObjRecordName(*ObjP, ObjRecName) != OK) {
  123.             Output(Warning, DumpFH,
  124.                     "\aNon-MS-Documented Record %02X in file %s.\n",
  125.                     *ObjP & 0x00FF, ObjName);
  126.             Output(Message, DumpFH, "      **%02X**:\n", *ObjP & 0x00FF);
  127.         }
  128.         else
  129.             Output(Message, DumpFH, "      %s:\n", ObjRecName);
  130.  
  131.         while (RecLength) {
  132.             PrintLength = (RecLength > MAXLN) ? MAXLN : RecLength;
  133.             PrintObjDumpLine(ObjP, DumpFH, LocCtr, PrintLength);
  134.             RecLength -= PrintLength;
  135.             FileLength   -= PrintLength;
  136.             LocCtr += PrintLength;
  137.             ObjP    += PrintLength;
  138.         }
  139.     }
  140.     fclose(DumpFH);
  141. }
  142.  
  143. /*----------------------------------------------------------
  144. *   PrintObjDumpLine -- print one line of formatted OBJ dump
  145. *----------------------------------------------------------*/
  146. PUBLIC void PrintObjDumpLine(char *src, FILE *dest, int LocCtr, 
  147.                              int PrintLength)
  148. {
  149.     int i;
  150.     static char line[100];
  151.     char *lptr = line;
  152.     char *aptr = line + ASCIICOL;
  153.  
  154.     memset(line, ' ', sizeof(line));
  155.     lptr += sprintf(lptr, "%04X    ", LocCtr);
  156.  
  157.     for (i = 0; i < PrintLength; i++, src++) {
  158.         if (i == 8) {
  159.             lptr += 3;
  160.             aptr += 2;
  161.         }
  162.         sprintf(lptr, "%02X", *src & 0x00FF);
  163.         *aptr++ = (CHKCHAR(*src)) ? (char) '.' : *src;
  164.         lptr += 2;
  165.         *lptr++ = ' ';
  166.     }
  167.     sprintf(aptr, "\n\0");
  168.     fputs(line, dest);
  169. }
  170.  
  171. /*-----------------------------------------------------
  172. *   Analyze -- Analyze the OBJ module records in detail
  173. *----------------------------------------------------*/
  174. PRIVATE void Analyze(
  175.     char Obj[],                 /* OBJ file in memory  */
  176.     long ObjLength,             /* PrintLength of OBJ  */
  177.     char *ObjName)              /* name of OBJ         */
  178.  
  179. {
  180.     char *RecordP = Obj;
  181.     unsigned char RecordType = '\0';
  182.     unsigned int  RecordLength;
  183.     char AnalysisFN[_MAX_PATH];
  184.     char RecordName[8];
  185.  
  186.     strcpy(AnalysisFN, ObjName);
  187.     strcat(AnalysisFN, ".ANL");
  188.  
  189.     if ((AnalysisFH = fopen(AnalysisFN, "w")) == NULL) {
  190.         fprintf(stderr, "\aCould Not Open File %s.\n", AnalysisFN);
  191.         exit(-1);
  192.     }
  193.  
  194.     while (ObjLength > 0L) {
  195.         RecordType = *RecordP;
  196.         if (GetObjRecordName(RecordType, RecordName) == OK)
  197.             Output(Message, AnalysisFH, "\n%04X   --   %s\n",
  198.                     GetRecordRelPos(RecordP), RecordName);
  199.         RecordP++;
  200.         RecordLength = *(int *) RecordP;
  201.         RecordP += 2;            /* advance ptr past type/PrintLength */
  202.         --RecordLength;          /* discount CHKSM */
  203.         ObjLength -= 4L;         /* discount CHKSM/type/PrintLength */
  204.  
  205.         switch(RecordType) {
  206.             case BLKDEF :        /* 0x7A */
  207.                 DoBLKDEF();
  208.                 break;
  209.             case BLKEND :        /* 0x7C : end-of-program-block indicator */
  210.                 DoBLKEND();
  211.                 break;
  212.             case THEADR :        /* 0x80 : Translator Header Record -- T  */
  213.                 DoTHEADR(RecordP);
  214.                 break;
  215.             case LHEADR :        /* 0x82 : Translator Header Record -- L  */
  216.                 DoLHEADR(RecordP);
  217.                 break;
  218.             case COMENT :        /* 0x88 : Comment Record */
  219.                 DoCOMENT(RecordP, RecordLength);
  220.                 break;
  221.             case MODEND :        /* 0x8A : Module End Record */
  222.                 DoMODEND(RecordP);
  223.                 break;
  224.             case EXTDEF :        /* 0x8C : External Definitions Record */
  225.                 DoEXTDEF(RecordP, RecordLength);
  226.                 break;
  227.             case TYPDEF :        /* 0x8E : Type Definitions Rec (obsolete)*/
  228.                 DoTYPDEF();
  229.                 break;
  230.             case PUBDEF :        /* 0x90 : Public Definitions Record */
  231.                 DoPUBDEF(RecordP, RecordLength);
  232.                 break;
  233.             case LINNUM :        /* 0x94 : Line Numbers Record */
  234.                 DoLINNUM(RecordP, RecordLength);
  235.                 break;
  236.             case LNAMES :        /* 0x96 : Names List Record */
  237.                 DoLNAMES(RecordP, RecordLength);
  238.                 break;
  239.             case SEGDEF :        /* 0x98 : Segment Definition Record */
  240.                 DoSEGDEF(RecordP);
  241.                 break;
  242.             case GRPDEF :        /* 0x9A : Group Definition Record  */
  243.                 DoGRPDEF(RecordP, RecordLength);
  244.                 break;
  245.             case FIXUPP :        /* 0x9C : References Fixup Record  */
  246.                 DoFIXUPP(RecordP, RecordLength);
  247.                 break;
  248.             case LEDATA :        /* 0xA0 : Enumerated Data Record   */
  249.                 DoLEDATA(RecordP, RecordLength);
  250.                 break;
  251.             case LIDATA :        /* 0xA2 : Iterated Data Record     */
  252.                 DoLIDATA(RecordP, RecordLength);
  253.                 break;
  254.             case COMDEF :        /* 0xA0 : Communal Names Definition Rec */
  255.                 DoCOMDEF(RecordP, RecordLength);
  256.                 break;
  257.             case BAKPAT:         /* 0xB2 : MS Extension: Quick-C backpatch */
  258.                 DoBAKPAT(RecordP, RecordLength);
  259.                 break;
  260.             case LEXTDEF:        /* 0xB4 : MS Extension: local EXTDEF */
  261.                 DoEXTDEF(RecordP, RecordLength);
  262.                 break;
  263.             case LPUBDEF:       /* 0xB6 : MS Extension: local PUBDEF */
  264.                 DoPUBDEF(RecordP, RecordLength);
  265.                 break;
  266.             case LCOMDEF:       /* 0xB8 : MS Extension: local COMDEF */
  267.                 DoCOMDEF(RecordP, RecordLength);
  268.                 break;
  269.  
  270.             default:            /* not recognized, undocumented, or error */
  271.                 Output(Warning, AnalysisFH,
  272.                         "Non-MS-Documented Record %02X at offset %Xx\n",
  273.                         RecordType & 0x00FF, (RecordP - Obj));
  274.                 break;
  275.         }
  276.         ObjLength -= (long) RecordLength;
  277.         RecordP += RecordLength;
  278.         ++RecordP;                         /* skip CHKSM        */
  279.     }
  280.  
  281.     if (ObjLength > 0L)     /* Any leftovers?  This should NOT happen! */
  282.         Output(Error, AnalysisFH,
  283.                 "OBJ module record not recognized. Terminating\n");
  284.  
  285.     fclose(AnalysisFH);
  286. }