
/***************************************************************************
**
**    $Header:   D:/EPSLDV1/SRC/LOG/SYMBLEXT.CPP   1.8   20 Jun 1996 09:28:58   ZJRD  $
**
**    $Log:   D:/EPSLDV1/SRC/LOG/SYMBLEXT.CPP  $
** 
**    Rev 1.8   20 Jun 1996 09:28:58   ZJRD
** EasyPack/SLD Version 1.20a
** 
**    Rev 1.6   10 Jun 1996 10:23:36   ZJRD
** EasyPack/SLD Version 1.20
** 
**    Rev 1.4   29 May 1996 09:34:58   ZJRD
** No change.
** 
**    Rev 1.3   16 May 1996 09:08:00   ZJRD
** No change.
** 
**    Rev 1.2   10 May 1996 09:09:32   ZJRD
** No change.
** 
**    Rev 1.1   02 May 1996 10:25:26   ZJRD
** EasyPack/SLD Version 1.92
** 
**    Rev 1.31   18 Apr 1996 13:00:08   Shirley
** No change.
** 
**    Rev 1.30   12 Apr 1996 10:35:26   Shirley
** EasyPack/SLD Version 1.90
** 
**    Rev 1.28   15 Feb 1996 08:50:40   Shirley
** No change.
** 
**    Rev 1.27   12 Feb 1996 14:05:22   Shirley
** No change.
** 
**    Rev 1.26   06 Feb 1996 15:31:54   Shirley
** No change.
** 
**    Rev 1.25   06 Feb 1996 13:45:08   Shirley
** No change.
** 
**    Rev 1.24   01 Feb 1996 10:17:56   Shirley
** No change.
** 
**    Rev 1.23   26 Jan 1996 09:16:04   Shirley
** No change.
** 
**    Rev 1.22   25 Jan 1996 13:15:58   Shirley
** No change.
** 
**    Rev 1.21   24 Jan 1996 10:35:42   Shirley
** No change.
** 
**    Rev 1.20   23 Jan 1996 11:28:58   Shirley
** No change.
** 
**    Rev 1.19   18 Jan 1996 10:13:52   Shirley
** No change.
** 
**    Rev 1.18   15 Jan 1996 16:10:42   Shirley
** No change.
** 
**    Rev 1.17   04 Jan 1996 11:10:00   Shirley
** No change.
** 
**    Rev 1.16   30 Nov 1995 09:13:22   Shirley
** No change.
** 
**    Rev 1.15   28 Nov 1995 15:35:42   Shirley
** No change.
** 
**    Rev 1.14   21 Nov 1995 11:23:46   Shirley
** No change.
** 
**    Rev 1.13   13 Nov 1995 09:26:08   Shirley
** No change.
** 
**    Rev 1.12   12 Nov 1995 11:29:48   Shirley
** No change.
** 
**    Rev 1.11   08 Nov 1995 16:31:36   Shirley
** No change.
** 
**    Rev 1.10   08 Nov 1995 12:40:10   Shirley
** No change.
** 
**    Rev 1.9   02 Nov 1995 10:08:32   Shirley
** No change.
** 
**    Rev 1.8   27 Oct 1995 16:46:00   Shirley
** No change.
** 
**    Rev 1.7   27 Oct 1995 13:44:58   Shirley
** No change.
** 
**    Rev 1.6   25 Oct 1995 14:31:22   Shirley
** No change.
** 
**    Rev 1.5   18 Oct 1995 14:47:16   Shirley
** No change.
** 
**    Rev 1.4   13 Oct 1995 13:19:18   Shirley
** No change.
** 
**    Rev 1.3   29 Sep 1995 09:51:46   Shirley
** No change.
** 
**    Rev 1.2   20 Sep 1995 10:53:08   Shirley
** No change.
** 
**    Rev 1.1   15 Sep 1995 09:49:26   Shirley
** No change.
** 
**    Rev 1.0   07 Sep 1995 09:53:26   Shirley
** Initial revision.
**
****************************************************************************/

/****************************************************************************
**
**  Name:  symblext.cpp
**
**  Description:
**     Contains Symbol Extended function definitions which handle bulk-data
**     access. 
**
**  Status: PRELIMINARY
**
**  $Log$
** 
**  $Header:   D:/EPSLDV1/SRC/LOG/SYMBLEXT.CPP   1.8   20 Jun 1996 09:28:58   ZJRD  $
**
**  Copyright (C) 1995 Microtek International.  All rights reserved.
**
*****************************************************************************/

                       /****************************
                        *                          *
                        *       INCLUDE FILES      *
                        *                          *
                        ****************************/
#include "stdafx.h"
#include "symblsvr.h"                      
#include "symblext.h"
#include "linenum.h"

                       /****************************
                        *                          *
                        *     LOCAL DEFINITIONS    *
                        *                          *
                        ****************************/

                       /****************************
                        *                          *
                        *    EXTERNAL VARIABLES    *
                        *                          *
                        ****************************/
//----------------------------------------------------------------------------
// Symbol Tables
extern MemPool st;       //
extern LinenumTable lt;  // defined in LINENUM.CPP
extern TABLE_OFFSET rootOffset;

//----------------------------------------------------------------------------
// Symbol Statistics 
extern U32 symbolStat[]; // defined in SYMADD.CPP

                       /****************************
                        *                          *
                        *     LOCAL PROTOTYPES     *
                        *                          *
                        ****************************/

                       /****************************
                        *                          *
                        *      EXECUTABLE CODE     *
                        *                          *
                        ****************************/
//-----------------------------------------------------------------------------
// SymGetSymStats
//-----------------------------------------------------------------------------
RETCODE EXPORT
SymGetSymStats(U16 FAR* numModules, U32 FAR* numFunctions, U32 FAR*
               numPublicLabels, U32 FAR* numUserLabels) {
   *numModules      = (U16)symbolStat[SYM_MODULE];
   *numFunctions    = symbolStat[SYM_FUNCTION];
   *numPublicLabels = symbolStat[SYM_PUBLIC_LABEL];
   *numUserLabels   = symbolStat[SYM_USER_DEFINED_LABEL];
   return GOOD;
}


//-----------------------------------------------------------------------------
// SymGetSiblingSymbols
//-----------------------------------------------------------------------------
RETCODE EXPORT
SymGetSiblingSymbols(SYM_DESCRIPTOR      symDesc,
                     SYM_TYPE_TYPE       basicSymType,
                     U16                 numRequested,
                     SYM_DESCRIPTOR FAR* symDescArray,
                     U16 FAR*            numReturned) {

   SYM_DESCRIPTOR headDesc = symDesc;
   HPU8 ptr;

   // Check for valid symbol type currently support by this routine
   if (!((basicSymType == SYM_MODULE) ||
         ((basicSymType == SYM_FUNCTION) && (symDesc != NULL_SYMBOL)) ||
         (basicSymType == SYM_PUBLIC_LABEL) ||
         (basicSymType == SYM_USER_DEFINED_LABEL)))
      return ER_INVALID_SYM_DESCRIPTOR;

   // Process each type of symbol
   switch(basicSymType) {
      case SYM_MODULE :
         // Get the list of modules from it head list
         RETCODE err;
         if ((symDesc == NULL_SYMBOL) &&
             ((err = SymGetModuleListHead(&headDesc)) != GOOD))
            return err;
         break;

      case SYM_PUBLIC_LABEL :
      case SYM_USER_DEFINED_LABEL:
         if (symDesc == NULL_SYMBOL) {
            ptr = st.GetHugeDataPtr(rootOffset);
            headDesc = ((COMMON_BLOCK_HEADER *)ptr)->list.labelListOffset;
         }
         break;
   }

   // make sure the headDesc is ok
   if (!UtilIsValidSymDescriptor(headDesc))
      return ER_INVALID_SYM_DESCRIPTOR;

   ptr = st.GetHugeDataPtr(headDesc);
   *numReturned = 0;

   // whether the numReturned count is excluding the input symbol
   // only count if the symDesc == NULL_SYMBOL
   if (symDesc == NULL_SYMBOL) {
     symDescArray[(*numReturned)] = headDesc;
     ++(*numReturned);
   }
    
   // Retrieve the list of siblings from the headDesc
   SYM_DESCRIPTOR nextSym;
   while (((nextSym = ((COMMON_BLOCK_HEADER *)ptr)->symHeader.symSiblingOffset)
          != NULL_SYMBOL) && ((*numReturned) < numRequested)) {
      symDescArray[(*numReturned)] = nextSym;
      ++(*numReturned);
      ptr = st.GetHugeDataPtr(nextSym);
   }        
   return GOOD;      
}

//-----------------------------------------------------------------------------
// SymGetChildSymbolsOfModule
//-----------------------------------------------------------------------------
RETCODE EXPORT
SymGetChildSymbolsOfModule(SYM_DESCRIPTOR      moduleDesc,
                           SYM_TYPE_TYPE       basicSymType,
                           U16                 numRequested,
                           SYM_DESCRIPTOR FAR* symDescArray,
                           U16 FAR*            numReturned) {
   RETCODE err;
   SYM_TYPE_TYPE  childType;
   SYM_DESCRIPTOR childDesc, nextChild;

   *numReturned = 0;
   // retrieve the first child <basicSymType> of the <moduleDesc> 
   if ((err = SymGetSymbolChild(moduleDesc, &childType, &childDesc)) != GOOD)
      return err;

   // return error if there is no child in <moduleDesc>
   if (childDesc == NULL_SYMBOL)
      return ER_SYMBOL_NOT_FOUND;

   // traverse the child list until we get the head of <basicSymType>
   while ((childType != basicSymType) && (childDesc != NULL_SYMBOL)) {
      if ((err = SymGetSymbolSibling(childDesc, &childType, &nextChild))
          != GOOD)
         return err;
      childDesc = nextChild;
   }

   // return error if childType is not what we are looking for
   if ((childDesc == NULL_SYMBOL) || (childType != basicSymType))
      return ER_SYMBOL_NOT_FOUND;

   // Save the first child descriptor to list
   symDescArray[0] = childDesc;
   ++(numReturned);

   // call to retrieve the rest of the requested list - increment the array
   U16 count;
   if ((err = SymGetSiblingSymbols(childDesc, basicSymType, numRequested-1,
           (symDescArray+1), &count)) != GOOD)
      return err;

   // update the numReturned with the count
   (*numReturned) += count;

   return GOOD;
}


//-----------------------------------------------------------------------------
// SymGetLineNumbersOfModule
//-----------------------------------------------------------------------------
RETCODE EXPORT
SymGetLineNumbersOfModule(SYM_DESCRIPTOR          moduleDesc,
                          U16                     numRequested,
                          LINENUM_DESCRIPTOR FAR* lineDescArray,
                          U16 FAR*                numReturned) {

   RETCODE err;
   LINENUM_DESCRIPTOR firstIndex;
   
   *numReturned = 0;
   // test for valid module desc 
   if (!UtilIsValidSymDescriptor(moduleDesc))
      return ER_ADDRESS_NOT_FOUND;

   // Get the first line number index of <moduleDesc>
   if ((err = SymGetLinenumFirstIndex(moduleDesc, &firstIndex)) != GOOD)
      return err;

   // Save the first index and get the rest
   lineDescArray[0] = firstIndex;
   ++(*numReturned);

   // retrieve the rest of the numRequested line indexes
   U16 count;
   if ((err = SymGetLineNumbersList(moduleDesc, firstIndex, numRequested-1,
          (lineDescArray+1), &count)) != GOOD)
      return err;

   // update the numReturned with the count
   (*numReturned) += count;

   return GOOD;
}

//-----------------------------------------------------------------------------
// SymGetLineNumbersList
//-----------------------------------------------------------------------------
RETCODE EXPORT
SymGetLineNumbersList(SYM_DESCRIPTOR          moduleDesc,
                      LINENUM_DESCRIPTOR      startLineDesc,
                      U16                     numRequested,
                      LINENUM_DESCRIPTOR FAR* lineDescArray,
                      U16 FAR*                numReturned) {

   // call the LinenumTable::GetLineNumbersList() to do the work
   return lt.GetLineNumbersList(moduleDesc,
                                startLineDesc,
                                numRequested,
                                lineDescArray,
                                numReturned);
} 

/********************************** E O F ***********************************/
