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

  1.  
  2. /***************************************************************************/
  3. /* CPROFILE - Utility routines which are static linked to an application   */
  4. /*          program to allow access to the features provided by the       */
  5. /*          program profile package.                       */
  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. #ifdef __TURBOC__
  21. #include <alloc.h>
  22. #else
  23. #include <malloc.h>
  24. #endif
  25. #include "profile.h"
  26.  
  27. #ifndef TRUE
  28. #define TRUE            1
  29. #define FALSE            0
  30. #endif
  31.  
  32. #ifdef __TURBOC__
  33. #define _fmalloc(size)        farmalloc((ulong) size)
  34. #define _ffree(ptr)        farfree(ptr)
  35. #endif
  36.  
  37. #define NO_ERRORS        0
  38. #define CANT_OPEN_PRF        1
  39. #define ERROR_READING_PRF    2
  40. #define INVALID_PRF_FILE    3
  41. #define OUT_OF_MEMORY        4
  42.  
  43.  
  44. struct sOfsEntry
  45. {
  46.     ushort    uOfs;
  47.     ulong    lCnt;
  48. };
  49. typedef struct sOfsEntry       OFSENTRY, *POFSENTRY, far *LPOFSENTRY;
  50.  
  51.  
  52. struct sSegEntry
  53. {
  54.     ushort    uSeg;
  55.     ushort    uNoLin;
  56.     ushort    uNoPub;
  57.     LPOFSENTRY    lpLin;
  58.     LPOFSENTRY    lpPub;
  59. };
  60. typedef struct sSegEntry       SEGENTRY, *PSEGENTRY, far *LPSEGENTRY;
  61.  
  62. extern short       StartProfile(char *);
  63. extern void       EndProfile(void);
  64. extern void       PrfInit(ushort, LPSEGENTRY);
  65. extern ulong       PrfTerm(void);
  66. extern ulong       PrfBiosCnt(void);
  67. extern ulong       PrfDosCnt(void);
  68. extern ulong       PrfHitCnt(void);
  69.  
  70. static void    near pascal WriteRptFile(FILE *, ulong);
  71. static short   near pascal LoadPrfTables(FILE *);
  72. static bool    near pascal ReadPrfRec(FILE *, PFILEREC);
  73.  
  74.  
  75. #ifdef __TURBOC__
  76. extern unsigned            _psp;   /* MSC has defined in stdlib.h */
  77. #endif
  78.  
  79. static ushort               uTotSegs = 0;
  80. static LPSEGENTRY           lpSegTab = (LPSEGENTRY) NULL;
  81. static LPOFSENTRY           lpLinTab = (LPOFSENTRY) NULL;
  82. static LPOFSENTRY           lpPubTab = (LPOFSENTRY) NULL;
  83. static ushort               uBaseSeg;
  84. static SEGENTRY            SegEntry;
  85. static OFSENTRY            OfsEntry;
  86. static char               InFileName[64];
  87.  
  88.  
  89.  
  90. short StartProfile(pFileName)
  91. char        *pFileName;
  92. {
  93.     auto     FILE    *PrfFile;
  94.     auto     char    *pStr;
  95.     auto     short     nStatus;
  96.  
  97.     pStr = strchr(strcpy(InFileName, pFileName), '.');
  98.     if (NULL != pStr)
  99.     *pStr = '\0';
  100.     strcat(InFileName, ".PRF");
  101.     PrfFile = fopen(InFileName, "rb");
  102.     if (NULL == PrfFile)
  103.     return(CANT_OPEN_PRF);
  104.     uBaseSeg = _psp + 0x10;
  105.     nStatus = LoadPrfTables(PrfFile);
  106.     fclose(PrfFile);
  107.     if (uTotSegs > 0)
  108.     PrfInit(uTotSegs, lpSegTab);
  109.     return(nStatus);
  110. }
  111.  
  112.  
  113. void EndProfile()
  114. {
  115.     auto     FILE     *Pr1File;
  116.     auto     ulong     lOtherCnt;
  117.  
  118.     if ((LPSEGENTRY) NULL == lpSegTab)
  119.     return;
  120.     lOtherCnt = PrfTerm();
  121.     strcpy(strchr(InFileName, '.'), ".PR1");
  122.     Pr1File = fopen(InFileName, "wb");
  123.     if (NULL != Pr1File)
  124.     {
  125.     WriteRptFile(Pr1File, lOtherCnt);
  126.     fclose(Pr1File);
  127.     }
  128.     _ffree(lpSegTab);
  129.     _ffree(lpLinTab);
  130.     _ffree(lpPubTab);
  131.     return;
  132. }
  133.  
  134.  
  135. static void near pascal WriteRptFile(Pr1File, lOtherCnt)
  136. FILE        *Pr1File;
  137. ulong         lOtherCnt;
  138. {
  139.     register short       i, j;
  140.     auto     LPOFSENTRY    lpOfsEntry;
  141.     auto     RPTREC       RptRec;
  142.     auto     ulong       lTotalTicks = 0L;
  143.  
  144.     RptRec.cRecType = RPT_OTH_REC;
  145.     RptRec.uSegOfs  = 0;
  146.     RptRec.lCnt     = lOtherCnt;
  147.     if (fwrite((char *) &RptRec, sizeof(RptRec), 1, Pr1File) != 1)
  148.     return;
  149.     RptRec.cRecType = RPT_BIO_REC;
  150.     RptRec.uSegOfs  = 0;
  151.     RptRec.lCnt     = PrfBiosCnt();
  152.     if (fwrite((char *) &RptRec, sizeof(RptRec), 1, Pr1File) != 1)
  153.     return;
  154.     RptRec.cRecType = RPT_DOS_REC;
  155.     RptRec.uSegOfs  = 0;
  156.     RptRec.lCnt     = PrfDosCnt();
  157.     if (fwrite((char *) &RptRec, sizeof(RptRec), 1, Pr1File) != 1)
  158.     return;
  159.     RptRec.cRecType = RPT_HIT_REC;
  160.     RptRec.uSegOfs  = 0;
  161.     RptRec.lCnt     = PrfHitCnt();
  162.     if (fwrite((char *) &RptRec, sizeof(RptRec), 1, Pr1File) != 1)
  163.     return;
  164.     for (i = uTotSegs - 1; i >= 0; --i)
  165.     {
  166.     if (0 == lpSegTab[i].uNoPub && 0 == lpSegTab[i].uNoLin)
  167.         continue;
  168.     RptRec.cRecType = RPT_SEG_REC;
  169.     RptRec.uSegOfs    = lpSegTab[i].uSeg - uBaseSeg;
  170.     RptRec.lCnt    = 0L;
  171.     if (fwrite((char *) &RptRec, sizeof(RptRec), 1, Pr1File) != 1)
  172.         return;
  173.     RptRec.cRecType = RPT_PUB_REC;
  174.     lpOfsEntry    = lpSegTab[i].lpPub + (lpSegTab[i].uNoPub - 1);
  175.     for (j = lpSegTab[i].uNoPub; j > 0; --j)
  176.     {
  177.         RptRec.uSegOfs = lpOfsEntry->uOfs;
  178.         RptRec.lCnt    = lpOfsEntry->lCnt;
  179.         if (RptRec.lCnt > 0L)
  180.         {
  181.         if (fwrite((char *) &RptRec, sizeof(RptRec),
  182.                     1, Pr1File) != 1)
  183.             return;
  184.         }
  185.         --lpOfsEntry;
  186.     }
  187.     RptRec.cRecType = RPT_LIN_REC;
  188.     lpOfsEntry    = lpSegTab[i].lpLin + (lpSegTab[i].uNoLin - 1);
  189.     for (j = lpSegTab[i].uNoLin; j > 0; --j)
  190.     {
  191.         RptRec.uSegOfs = lpOfsEntry->uOfs;
  192.         RptRec.lCnt    = lpOfsEntry->lCnt;
  193.         if (RptRec.lCnt > 0L)
  194.         {
  195.         if (fwrite((char *) &RptRec, sizeof(RptRec),
  196.                     1, Pr1File) != 1)
  197.             return;
  198.         }
  199.         --lpOfsEntry;
  200.         lTotalTicks += RptRec.lCnt;
  201.     }
  202.     }
  203.     memset((char *) &RptRec, 0, sizeof(RptRec));
  204.     RptRec.cRecType = RPT_EOF_REC;
  205.     RptRec.lCnt     = lTotalTicks;
  206.     fwrite((char *) &RptRec, sizeof(RptRec), 1, Pr1File);
  207.     return;
  208. }
  209.  
  210.  
  211. static short near pascal LoadPrfTables(PrfFile)
  212. FILE        *PrfFile;
  213. {
  214.     register short        i;
  215.     auto     ushort        uNoSegs, uNoLins, uNoPubs;
  216.     auto     FILEREC        PrfRec;
  217.  
  218.     if (!ReadPrfRec(PrfFile, &PrfRec))
  219.     return(ERROR_READING_PRF);
  220.     if (PRF_ID_REC == REC_TYPE && PRF_FILE_VER == FILE_VER)
  221.     {
  222.     if (memcmp(FILE_ID, PRF_FILE_ID, sizeof(FILE_ID)) != 0)
  223.         return(INVALID_PRF_FILE);
  224.     }
  225.     else
  226.     return(INVALID_PRF_FILE);
  227.  
  228.     if (!ReadPrfRec(PrfFile, &PrfRec))
  229.     return(ERROR_READING_PRF);
  230.     if (PRF_HDR_REC != REC_TYPE)
  231.     return(INVALID_PRF_FILE);
  232.     uNoSegs = uTotSegs = NO_SEGS;
  233.     uNoLins = NO_LINS;
  234.     uNoPubs = NO_PUBS;
  235.     lpSegTab = (LPSEGENTRY) _fmalloc(uNoSegs * sizeof(SEGENTRY));
  236.     if ((LPSEGENTRY) NULL == lpSegTab)
  237.     return(OUT_OF_MEMORY);
  238.     lpLinTab = (LPOFSENTRY) _fmalloc(uNoLins * sizeof(OFSENTRY));
  239.     if ((LPOFSENTRY) NULL == lpLinTab)
  240.     {
  241.     _ffree(lpSegTab);
  242.     lpSegTab = (LPSEGENTRY) NULL;
  243.     return(OUT_OF_MEMORY);
  244.     }
  245.     lpPubTab = (LPOFSENTRY) _fmalloc(uNoPubs * sizeof(OFSENTRY));
  246.     if ((LPOFSENTRY) NULL == lpPubTab)
  247.     {
  248.     _ffree(lpSegTab);
  249.     _ffree(lpLinTab);
  250.     lpSegTab = (LPSEGENTRY) NULL;
  251.     return(OUT_OF_MEMORY);
  252.     }
  253.     while (PRF_EOF_REC != REC_TYPE)
  254.     {
  255.     if (!ReadPrfRec(PrfFile, &PrfRec))
  256.         return(ERROR_READING_PRF);
  257.     switch (REC_TYPE)
  258.     {
  259.         case PRF_SEG_REC:
  260.         memset((char *) &SegEntry, 0, sizeof(SegEntry));
  261.         SegEntry.uSeg        = SEG_VAL + uBaseSeg;
  262.         lpSegTab[--uNoSegs] = SegEntry;
  263.         break;
  264.         case PRF_PUB_REC:
  265.         PUB_SEG += uBaseSeg;
  266.         for (i = 0; TRUE; ++i)
  267.         {
  268.             if (PUB_SEG == lpSegTab[i].uSeg)
  269.             break;
  270.         }
  271.         OfsEntry.uOfs = PUB_OFS;
  272.         OfsEntry.lCnt = 0L;
  273.         lpPubTab[--uNoPubs] = OfsEntry;
  274.         lpSegTab[i].uNoPub++;
  275.         lpSegTab[i].lpPub = &lpPubTab[uNoPubs];
  276.         break;
  277.         case PRF_LIN_REC:
  278.         LIN_SEG += uBaseSeg;
  279.         for (i = 0; TRUE; ++i)
  280.         {
  281.             if (LIN_SEG == lpSegTab[i].uSeg)
  282.             break;
  283.         }
  284.         OfsEntry.uOfs = LIN_OFS;
  285.         OfsEntry.lCnt = 0L;
  286.         lpLinTab[--uNoLins] = OfsEntry;
  287.         lpSegTab[i].uNoLin++;
  288.         lpSegTab[i].lpLin = &lpLinTab[uNoLins];
  289.         break;
  290.     }
  291.     }
  292.     return(NO_ERRORS);
  293. }
  294.  
  295.  
  296. static bool near pascal ReadPrfRec(PrfFile, PrfRec)
  297. FILE        *PrfFile;
  298. PFILEREC     PrfRec;
  299. {
  300.     if (fread((char *) PrfRec, sizeof(FILEPFX), 1, PrfFile) != 1)
  301.     return(FALSE);
  302.     if (fread((char *) &PrfRec->Rec,
  303.           PrfRec->Pfx.uRecLen - sizeof(FILEPFX), 1, PrfFile) != 1)
  304.     return(FALSE);
  305.     return(TRUE);
  306. }
  307.