home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Interactive Guide / c-cplusplus-interactive-guide.iso / c_ref / csource4 / 259_01 / makeprf.c < prev    next >
Text File  |  1988-02-25  |  13KB  |  526 lines

  1.  
  2. /***************************************************************************/
  3. /* MAKEPRF - Utility used to generate a .PRF symbol file for use in the    */
  4. /*         program profile utility package.                   */
  5. /*                                       */
  6. /*                                       */
  7. /***************************************************************************/
  8. /*                 Modification Log                   */
  9. /***************************************************************************/
  10. /* Version   Date   Programmer     -----------  Description  --------------- */
  11. /*                                       */
  12. /* V01.00   010788  Bob Withers  Program intially complete.           */
  13. /*                                       */
  14. /*                                       */
  15. /***************************************************************************/
  16.  
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include <string.h>
  20. #include <ctype.h>
  21. #include "profile.h"
  22.  
  23. #ifndef TRUE
  24. #define TRUE            1
  25. #define FALSE            0
  26. #endif
  27.  
  28. #define STATIC            static
  29.  
  30.  
  31. STATIC void    near pascal ProcessMapFile(FILE *, FILE *);
  32. STATIC void    near pascal WritePrfID(FILE *);
  33. STATIC long    near pascal WritePrfHdr(FILE *);
  34. STATIC short   near pascal WriteSegRec(FILE *, char *);
  35. STATIC short   near pascal WritePubRec(FILE *, char *);
  36. STATIC short   near pascal WriteLinRec(FILE *, char *);
  37. STATIC short   near pascal WriteModRec(FILE *, char *);
  38. STATIC ulong   near pascal GetHexVal(char *);
  39. STATIC ushort  near pascal GetDecVal(char *);
  40. STATIC void    near pascal BuildMapFileName(char *, char *);
  41. STATIC void    near pascal BuildPrfFileName(char *, char *);
  42. STATIC void    near pascal WriteError(FILE *);
  43. STATIC void    near pascal ErrorMsg(char *);
  44.  
  45. STATIC short           nCurModNum = -1;
  46. STATIC char           cRevision[] = "$Revision:   1.0  $";
  47. STATIC char           cMapFileName[MAX_PATHNAME];
  48. STATIC char           cPrfFileName[16];
  49. STATIC FILEREC           PrfRec;
  50. STATIC char           cWrk[512];
  51. STATIC ushort           uMaxSegs = 0;
  52. STATIC ushort           uSegs[MAX_SEGMENTS];
  53.  
  54.  
  55. int main(argc, argv)
  56. int      argc;
  57. char    **argv;
  58. {
  59.     auto     char    *pRev;
  60.     auto     FILE    *MapFile, *PrfFile;
  61.  
  62.     for (pRev = cRevision; *pRev; ++pRev)
  63.     {
  64.     if ('$' == *pRev)
  65.         *pRev = SPACE;
  66.     }
  67.     sprintf(cWrk, "Profile Symbol File Generator %s", cRevision);
  68.     ErrorMsg(cWrk);
  69.     ErrorMsg("Public Domain Software by Bob Withers, 1988");
  70.     if (argc < 2)
  71.     {
  72.     ErrorMsg("\nError - command usage is:");
  73.     ErrorMsg("        MAKEPRF mapfile");
  74.     ErrorMsg("           ^       ^");
  75.     ErrorMsg("           |       |");
  76.     ErrorMsg("           |       +---- Name of .MAP file from linker");
  77.     ErrorMsg("           +------------ Utility program name");
  78.     return(1);
  79.     }
  80.     BuildMapFileName(argv[1], cMapFileName);
  81.     BuildPrfFileName(cMapFileName, cPrfFileName);
  82.     MapFile = fopen(cMapFileName, "rt");
  83.     if (NULL == MapFile)
  84.     {
  85.     sprintf(cWrk, "\nUnable to open input file %s", cMapFileName);
  86.     ErrorMsg(cWrk);
  87.     return(2);
  88.     }
  89.     PrfFile = fopen(cPrfFileName, "wb");
  90.     if (NULL == PrfFile)
  91.     {
  92.     sprintf(cWrk, "\nUnable to open output file %s", cPrfFileName);
  93.     ErrorMsg(cWrk);
  94.     return(3);
  95.     }
  96.     ProcessMapFile(MapFile, PrfFile);
  97.     fclose(PrfFile);
  98.     fclose(MapFile);
  99.     return(0);
  100. }
  101.  
  102.  
  103. STATIC void near pascal ProcessMapFile(MapFile, PrfFile)
  104. FILE        *MapFile, *PrfFile;
  105. {
  106.     register char    *pPtr;
  107.     register char     cStatus  = SPACE;
  108.     auto     short    nSegRecs = 0, nModRecs = 0, nPubRecs = 0, nLinRecs = 0;
  109.     auto     long     lHdrPos;
  110.  
  111.     WritePrfID(PrfFile);
  112.     lHdrPos = WritePrfHdr(PrfFile);
  113.     cStatus = 'S';
  114.     while (TRUE)
  115.     {
  116.     pPtr = fgets(cWrk, sizeof(cWrk), MapFile);
  117.     if (NULL == pPtr)
  118.         break;
  119.     if ('\n' == cWrk[0])
  120.         continue;
  121.     if (strstr(cWrk, "Publics by Value") != NULL)
  122.         cStatus = 'P';
  123.     if (strstr(cWrk, "Publics by Name") != NULL)
  124.         cStatus = SPACE;
  125.     if (strstr(cWrk, "Origin ") != NULL)
  126.         cStatus = SPACE;
  127.     if (strstr(cWrk, "Detailed map") != NULL)
  128.         cStatus = SPACE;
  129.     if (strstr(cWrk, "Line numbers") != NULL)
  130.     {
  131.         nModRecs += WriteModRec(PrfFile, cWrk);
  132.         cStatus = 'L';
  133.         continue;
  134.     }
  135.     switch (cStatus)
  136.     {
  137.         case 'S':
  138.         nSegRecs += WriteSegRec(PrfFile, cWrk);
  139.         break;
  140.         case 'P':
  141.         nPubRecs += WritePubRec(PrfFile, cWrk);
  142.         break;
  143.         case 'L':
  144.         nLinRecs += WriteLinRec(PrfFile, cWrk);
  145.         break;
  146.     }
  147.     }
  148.  
  149.     REC_TYPE = PRF_EOF_REC;
  150.     REC_LEN  = sizeof(FILEPFX) + 1;
  151.     if (fwrite((char *) &PrfRec, 1, REC_LEN, PrfFile) != REC_LEN)
  152.     WriteError(PrfFile);
  153.  
  154.     if (fseek(PrfFile, lHdrPos, SEEK_SET) != 0)
  155.     WriteError(PrfFile);
  156.     NO_SEGS = nSegRecs;
  157.     NO_PUBS = nPubRecs;
  158.     NO_LINS = nLinRecs;
  159.     NO_MODS = nModRecs;
  160.     WritePrfHdr(PrfFile);
  161.     sprintf(cWrk,
  162.       "\nProcessed:\n%5d Segment(s)\n%5d Public Symbol(s)",
  163.       nSegRecs, nPubRecs);
  164.     ErrorMsg(cWrk);
  165.     sprintf(cWrk, "%5d Module(s)\n%5d Line Number(s)", nModRecs, nLinRecs);
  166.     ErrorMsg(cWrk);
  167.     return;
  168. }
  169.  
  170.  
  171. STATIC void near pascal WritePrfID(PrfFile)
  172. FILE        *PrfFile;
  173. {
  174.     memset((char *) &PrfRec, SPACE, sizeof(PrfRec));
  175.     REC_TYPE = PRF_ID_REC;
  176.     FILE_VER = PRF_FILE_VER;
  177.     memcpy(FILE_ID, PRF_FILE_ID, sizeof(FILE_ID));
  178.     REC_LEN  = sizeof(FILEID) + sizeof(FILEPFX);
  179.     if (fwrite((char *) &PrfRec, 1, REC_LEN, PrfFile) != REC_LEN)
  180.     WriteError(PrfFile);
  181.     return;
  182. }
  183.  
  184.  
  185. STATIC long near pascal WritePrfHdr(PrfFile)
  186. FILE        *PrfFile;
  187. {
  188.     auto     long      lHdrPos;
  189.  
  190.     lHdrPos  = ftell(PrfFile);
  191.     REC_TYPE = PRF_HDR_REC;
  192.     REC_LEN  = sizeof(FILEHDR) + sizeof(FILEPFX);
  193.     if (fwrite((char *) &PrfRec, 1, REC_LEN, PrfFile) != REC_LEN)
  194.     WriteError(PrfFile);
  195.     return(lHdrPos);
  196. }
  197.  
  198.  
  199. STATIC short near pascal WriteSegRec(PrfFile, pMapRec)
  200. FILE         *PrfFile;
  201. register char     *pMapRec;
  202. {
  203.     /*    is this really a segment record?  */
  204.     while (SPACE == *pMapRec)
  205.     ++pMapRec;
  206.     if (*pMapRec < '0' || *pMapRec > '9')
  207.     return(0);
  208.  
  209.     /*    get the segment value  */
  210.     SEG_VAL = (ushort) (GetHexVal(pMapRec) >> 4);
  211.  
  212.     /*    skip the Stop value and pick up the segment length  */
  213.     while (SPACE != *pMapRec++)     /* skip 'Stop' value */
  214.     ;
  215.     while (SPACE != *pMapRec++)
  216.     ;
  217.     SEG_LEN = (ushort) GetHexVal(pMapRec);
  218.  
  219.     /*    pick up the segment name  */
  220.     while (SPACE != *pMapRec++)
  221.     ;
  222.     while (SPACE == *pMapRec)
  223.     ++pMapRec;
  224.     SEG_NAME_LEN = 0;
  225.     while (! (SPACE == *pMapRec || '\0' == *pMapRec || '\n' == *pMapRec))
  226.     SEG_NAMES[SEG_NAME_LEN++] = *pMapRec++;
  227.  
  228.     /*    pick up the class name    */
  229.     while (SPACE == *pMapRec)
  230.     ++pMapRec;
  231.     SEG_CLASS_LEN = SEG_NAME_LEN;
  232.     while (! (SPACE == *pMapRec || '\0' == *pMapRec || '\n' == *pMapRec))
  233.     SEG_NAMES[SEG_CLASS_LEN++] = *pMapRec++;
  234.     SEG_CLASS_LEN -= SEG_NAME_LEN;
  235.  
  236.     /*    allow only segment with class 'CODE', remove this if for all segs  */
  237.     if (memcmp(&SEG_NAMES[SEG_NAME_LEN], "CODE ", SEG_CLASS_LEN) != 0)
  238.     return(0);
  239.  
  240.     if (uMaxSegs < MAX_SEGMENTS)
  241.     uSegs[uMaxSegs++] = SEG_VAL;
  242.     else
  243.     return(0);
  244.  
  245.     /*    write the segment record to the .PRF file  */
  246.     REC_TYPE = PRF_SEG_REC;
  247.     REC_LEN  = sizeof(FILEPFX) + sizeof(FILESEG) - MAX_SEGNAME_LEN
  248.             + SEG_NAME_LEN + SEG_CLASS_LEN;
  249.     if (fwrite((char *) &PrfRec, 1, REC_LEN, PrfFile) != REC_LEN)
  250.     WriteError(PrfFile);
  251.  
  252.     return(1);
  253. }
  254.  
  255.  
  256. STATIC short near pascal WritePubRec(PrfFile, pMapRec)
  257. FILE        *PrfFile;
  258. register char    *pMapRec;
  259. {
  260.     register short     i;
  261.  
  262.     /*    is this really a pubdef record?  */
  263.     while (SPACE == *pMapRec)
  264.     ++pMapRec;
  265.     if (*pMapRec < '0' || *pMapRec > '9')
  266.     return(0);
  267.  
  268.     /* pick up the public symbol's segment value  */
  269.     PUB_SEG = (ushort) GetHexVal(pMapRec);
  270.     for (i = 0; i < uMaxSegs; ++i)
  271.     {
  272.     if (uSegs[i] == PUB_SEG)
  273.         break;
  274.     }
  275.     if (i >= uMaxSegs)
  276.     return(0);
  277.  
  278.     /*    pick up the public symbol's offset value  */
  279.     while (':' != *pMapRec++)
  280.     ;
  281.     PUB_OFS = (ushort) GetHexVal(pMapRec);
  282.  
  283.     /*    position pointer and check for absolute value  */
  284.     while (SPACE != *pMapRec)
  285.     ++pMapRec;
  286.     while (SPACE == *pMapRec)
  287.     ++pMapRec;
  288.     if (memcmp(pMapRec, "Abs ", 4) == 0)
  289.     {
  290.     PUB_ABS = TRUE;
  291.     while (SPACE != *pMapRec)
  292.         ++pMapRec;
  293.     while (S