home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_200 / 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 (SPACE == *pMapRec)
  294.         ++pMapRec;
  295.     }
  296.     else
  297.     PUB_ABS = FALSE;
  298.  
  299.     /*    pick up the public symbol's name  */
  300.     PUB_NAME_LEN = 0;
  301.     while (! (SPACE == *pMapRec || '\0' == *pMapRec || '\n' == *pMapRec))
  302.     PUB_NAME[PUB_NAME_LEN++] = *pMapRec++;
  303.  
  304.     /*    remove following code to include absolute addresses  */
  305.     if (PUB_ABS)
  306.     return(0);
  307.  
  308.     /*    write the public record to the .PRF file  */
  309.     REC_TYPE = PRF_PUB_REC;
  310.     REC_LEN  = sizeof(FILEPFX) + sizeof(FILEPUB) - MAX_PUBNAME_LEN
  311.                    + PUB_NAME_LEN;
  312.     if (fwrite((char *) &PrfRec, 1, REC_LEN, PrfFile) != REC_LEN)
  313.     WriteError(PrfFile);
  314.  
  315.     return(1);
  316. }
  317.  
  318.  
  319. STATIC short near pascal WriteLinRec(PrfFile, pMapRec)
  320. FILE        *PrfFile;
  321. register char    *pMapRec;
  322. {
  323.     register short    i;
  324.     auto     short    nRecCnt = 0;
  325.  
  326.     while (SPACE == *pMapRec)
  327.     ++pMapRec;
  328.     if (*pMapRec < '0' || *pMapRec > '9')
  329.     return(0);
  330.  
  331.     REC_TYPE = PRF_LIN_REC;
  332.     REC_LEN  = sizeof(FILEPFX) + sizeof(FILELIN);
  333.     while (! ('\0' == *pMapRec || '\n' == *pMapRec))
  334.     {
  335.     LIN_MOD_NUM = nCurModNum;
  336.     LIN_NO        = GetDecVal(pMapRec);
  337.     while (SPACE != *pMapRec)
  338.         ++pMapRec;
  339.     while (SPACE == *pMapRec)
  340.         ++pMapRec;
  341.     LIN_SEG = (ushort) GetHexVal(pMapRec);
  342.     while (':' != *pMapRec++)
  343.         ;
  344.     LIN_OFS = (ushort) GetHexVal(pMapRec);
  345.     while (! (SPACE == *pMapRec || '\n' == *pMapRec || '\0' == pMapRec))
  346.         ++pMapRec;
  347.     while (SPACE == *pMapRec)
  348.         ++pMapRec;
  349.     for (i = 0; i < uMaxSegs; ++i)
  350.     {
  351.         if (uSegs[i] == LIN_SEG)
  352.         break;
  353.     }
  354.     if (i < uMaxSegs)
  355.     {
  356.         if (fwrite((char *) &PrfRec, 1, REC_LEN, PrfFile) != REC_LEN)
  357.         WriteError(PrfFile);
  358.         ++nRecCnt;
  359.     }
  360.     }
  361.     return(nRecCnt);
  362. }
  363.  
  364.  
  365. STATIC short near pascal WriteModRec(PrfFile, pMapRec)
  366. FILE        *PrfFile;
  367. register char    *pMapRec;
  368. {
  369.     register short    i;
  370.  
  371.     pMapRec = strchr(pMapRec, '(');
  372.     if (NULL != pMapRec)
  373.     {
  374.     MOD_NUM      = (uchar) ++nCurModNum;
  375.     ++pMapRec;
  376.     for (i = 0; *pMapRec != ')' && i < MAX_MODNAME_LEN; ++i, ++pMapRec)
  377.         MOD_NAME[i] = toupper(*pMapRec);
  378.     MOD_NAME_LEN = (uchar) i;
  379.     REC_TYPE     = PRF_MOD_REC;
  380.     REC_LEN      = sizeof(FILEPFX) + sizeof(FILEMOD) - MAX_MODNAME_LEN
  381.                        + MOD_NAME_LEN;
  382.     if (fwrite((char *) &PrfRec, 1, REC_LEN, PrfFile) != REC_LEN)
  383.         WriteError(PrfFile);
  384.     return(1);
  385.     }
  386.     return(0);
  387. }
  388.  
  389.  
  390. STATIC ulong near pascal GetHexVal(pStr)
  391. register char     *pStr;
  392. {
  393.     auto     bool    bDone    = FALSE;
  394.     auto     ulong    lHexVal = 0L;
  395.  
  396.     while (SPACE == *pStr)
  397.     ++pStr;
  398.     while (! bDone)
  399.     {
  400.     switch (*pStr)
  401.     {
  402.         case '0':
  403.         case '1':
  404.         case '2':
  405.         case '3':
  406.         case '4':
  407.         case '5':
  408.         case '6':
  409.         case '7':
  410.         case '8':
  411.         case '9':
  412.         lHexVal = (lHexVal << 4) + (ulong) (*pStr - '0');
  413.         break;
  414.         case 'A':
  415.         case 'B':
  416.         case 'C':
  417.         case 'D':
  418.         case 'E':
  419.         case 'F':
  420.         lHexVal = (lHexVal << 4) + (ulong) (*pStr - 'A' + 10);
  421.         break;
  422.         case 'a':
  423.         case 'b':
  424.         case 'c':
  425.         case 'd':
  426.         case 'e':
  427.         case 'f':
  428.         lHexVal = (lHexVal << 4) + (ulong) (*pStr - 'a' + 10);
  429.         break;
  430.         default:
  431.         bDone = TRUE;
  432.         break;
  433.     }
  434.     ++pStr;
  435.     }
  436.     return(lHexVal);
  437. }
  438.  
  439.  
  440. STATIC ushort near pascal GetDecVal(pStr)
  441. register char     *pStr;
  442. {
  443.     auto     bool    bDone    = FALSE;
  444.     auto     ushort    nDecVal = 0;
  445.  
  446.     while (SPACE == *pStr)
  447.     ++pStr;
  448.     while (! bDone)
  449.     {
  450.     switch (*pStr)
  451.     {
  452.         case '0':
  453.         case '1':
  454.         case '2':
  455.         case '3':
  456.         case '4':
  457.         case '5':
  458.         case '6':
  459.         case '7':
  460.         case '8':
  461.         case '9':
  462.         nDecVal = (nDecVal * 10) + (ushort) (*pStr - '0');
  463.         break;
  464.         default:
  465.         bDone = TRUE;
  466.         break;
  467.     }
  468.     ++pStr;
  469.     }
  470.     return(nDecVal);
  471. }
  472.  
  473.  
  474. STATIC void near pascal BuildMapFileName(pInName, pOutName)
  475. char      *pInName, *pOutName;
  476. {
  477.     register char      *pPtr;
  478.  
  479.     pPtr = strchr(strupr(strcpy(pOutName, pInName)), '.');
  480.     if (NULL == pPtr)
  481.     strcat(pOutName, ".MAP");
  482.     return;
  483. }
  484.  
  485.  
  486. STATIC void near pascal BuildPrfFileName(pInName, pOutName)
  487. char        *pInName, *pOutName;
  488. {
  489.     register char    *pPtr;
  490.     auto     short     nCnt = 0;
  491.  
  492.     pPtr = strchr(pInName, '.');
  493.     if (NULL != pPtr)
  494.     {
  495.     --pPtr;
  496.     while (pPtr >= pInName)
  497.     {
  498.         if ('\\' == *pPtr || ':' == *pPtr)
  499.         break;
  500.         ++nCnt;
  501.         --pPtr;
  502.     }
  503.     memcpy(pOutName, pPtr + 1, nCnt);
  504.     }
  505.     pOutName[nCnt] = '\0';
  506.     strcat(pOutName, ".PRF");
  507.     return;
  508. }
  509.  
  510.  
  511. STATIC void near pascal WriteError(OutFile)
  512. FILE     *OutFile;
  513. {
  514.     fclose(OutFile);
  515.     ErrorMsg("\nError while writing output file - disk full?");
  516.     exit(4);
  517. }
  518.  
  519.  
  520. STATIC void near pascal ErrorMsg(pStr)
  521. char        *pStr;
  522. {
  523.     fprintf(stderr, "%s\n", pStr);
  524.     return;
  525. }
  526.