/*----------------------------------------------------------------------------
** Name: linenum.h
**
** Title: Line Number Table
**
** Purpose:
**  Classes and methods declarations for managing the line numbers
**
** Status: TESTED
**
** $Log:   S:/tbird/mt2_186/symbol/linenum.h_v  $
** 
**    Rev 1.2   22 Jul 1997 10:10:24   Judy
** 
**    Rev 1.1   26 Feb 1997 11:42:56   Judy
** 
**    Rev 1.1   14 Jan 1997 15:30:54   Judy
** No change.
** 
**    Rev 1.0   14 Jun 1996 16:42:02   Judy
** Initial revision.
** 
**    Rev 1.24   24 May 1995 17:46:20   nghia
** Fixed bug in GetLinenumCount() - shouldn't subtract the number of modules
** loaded.  
** 
**    Rev 1.23   10 Feb 1995 09:26:22   nghia
** Added GetLastLinenum() to LinenumTable class.
** Revised GetLinenumFirstLast() to take pointers for output instead of
** references.
** 
**    Rev 1.22   03 Aug 1994 12:09:16   brucea
** Added: UpdateLinenumEndAddr prototype
** 
**    Rev 1.21   28 Jul 1994 13:13:50   brucea
** Added declaration for LinenumCompare
** 
**    Rev 1.20   20 Jun 1994 09:59:02   nghia
** Added GetLineNumbersList to class.
** 
**    Rev 1.19   12 Feb 1993 17:40:20   brucea
** Removed #if 0 headers
** 
**    Rev 1.18   08 Nov 1992 13:46:52   nghia
** Added prototype for GetLinenumInOrder() to fix ppr 7517 and 7520.
** This routine is private to SymGetLinenumInOrder() only.
** 
**    Rev 1.18   08 Nov 1992 13:42:34   nghia
** Added prototype for GetLinenumInOrder() to fix ppr 7517 and 7520.
** This routine is private to SymGetLinenumInOrder() only.
** 
**    Rev 1.18   08 Nov 1992 13:41:32   nghia
** Added prototype for GetLinenumInOrder() to fix ppr 7517 and 7520.
** This routine is private to the Source Presenter only.
** 
**    Rev 1.17   06 Nov 1992 07:13:56   brucea
** Fixed: calculation bug in ::GetLinenumCount
** 
**    Rev 1.16   06 Aug 1992 22:07:10   brucea
** Removed: ::IsModuleCached and prototype of ::AreThereLinenums
** 
** 
**    Rev 1.15   27 Jul 1992 23:30:56   brucea
** Added: private var modulesLoaded, removed duplicateLinenums
** Fixed: calculation of GetLinenumCount
** 
**    Rev 1.14   25 Jul 1992 16:39:24   brucea
** Added: ::AreThereLinenums
** 
**    Rev 1.13   19 Jul 1992 21:18:36   brucea
** Added: previousLinenumOffset to private vars - holds the location of previous
**    linenum so it can be modified if the next has the same address
** 
**    Rev 1.12   10 Jul 1992 18:39:32   brucea
** Added: GetLinenumCount
** 
**    Rev 1.11   21 Apr 1992 16:54:16   brucea
** Added: Prototype for LinenumTable::ObliterateTable
** 
**    Rev 1.10   20 Apr 1992 09:16:52   brucea
** Changed: previousAddr to previousLine to support removal of duplicate lines
** Added: duplicateLinenums to sum the number of duplicate lines removed
** Added: GetRawLinenumByIndex, GetLinenumFirstIndex
** 
**    Rev 1.9   12 Mar 1992 22:47:20   brucea
** Added: SYM_LINE_TYPE
** Modified: (internal) MapAddr2Linenum interface, added lineType
** 
**    Rev 1.8   20 Dec 1991 15:16:40   brucea
** Added LinenumTable::GetLinenumFirstLast prototype
** 
**    Rev 1.7   17 Dec 1991 16:10:04   john
** Changed prototype for LinenumStart.
** 
**    Rev 1.6   12 Dec 1991 14:59:20   brucea
** removed EXPORT from member functions
** 
**    Rev 1.5   11 Dec 1991 16:09:42   brucea
** Changes below:
** Added prototypes for: GetLinenumByIndex, GetLinenumStmtByIndex,
**   LinenumTable::IsModuleLoaded (includes code)
** 
**    Rev 1.4   09 Dec 1991 17:38:40   brucea
** Changes follow:
** Added MAX_COLUMN, changed loadState to linenumLoadState
** Added prototypes for: GetLinenumStmt, UpdateCacheParams
** 
**    Rev 1.3   29 Nov 1991 19:50:14   brucea
** For function parameters:
**   changed LOGICAL_ADDR_TYPE to OFFSET_ADDR_TYPE
**   changed COMP_ADDR_RANGE_TYPE to an address DESCRIPTOR
** 
**    Rev 1.2   18 Nov 1991 15:25:10   brucea
** Added #include symutil.h
** Created #define LINENUM_STRUCT_SIZE
** Added definition for LinenumTable::MapAddr2Linenum
** 
**    Rev 1.1   13 Nov 1991 17:49:42   brucea
** Made structure comments with standard C comments so will compile under C
** Added function comment header
**
**    Rev 1.0   12 Nov 1991 10:06:52   brucea
** Initial revision.
** 
** $Header:   S:/tbird/mt2_186/symbol/linenum.h_v   1.2   22 Jul 1997 10:10:24   Judy  $
**
** Copyright (C) 1991 Microtek International.  All rights reserved.
**
**--------------------------------------------------------------------------*/

#define _LINENUM_

#ifndef _MEMPOOL_
#include "mempool.h"
#endif

#ifndef _SYMBLSVR_
#include "symblsvr.h"
#endif

#ifndef _SYMMGR_
#include "symmgr.h"
#endif

#ifndef _SYMUTIL_
#include "symutil.h"
#endif


                       /****************************
                        *                          *
                        *        DEFINITIONS       *
                        *                          *
                        ****************************/

typedef U32 LINENUM_INDEX;

typedef struct {
   U16  segment; //Hera 6/3/97
   OFFSET_ADDR_TYPE  addr;    /* logical address of linenum */
   LINENUM_TYPE      linenum; /* integer value of line number */
   U8                column;  /* column position in source */
                              /*    0 ==> end of source line  */
   U8                dummy;   /* fill so struct is an even 8 bytes long */
} LINENUM_STRUCT_TYPE;

#define LINENUM_STRUCT_SIZE (sizeof(LINENUM_STRUCT_TYPE))

typedef enum {LOADING, NOT_LOADING} LOAD_STATE;

typedef enum {
   SYM_LINE,  // specifies entire line
   SYM_STMT   // specifies statement within line
} SYM_LINE_TYPE;

                       /**********************************
                        *                                *
                        *   MEMBER FUNCTION PROTOTYPES   *
                        *                                *
                        **********************************/

#ifdef __cplusplus

class LinenumTable : public MemPool {

private:
   U32 linenumOffsetStart;    // table offset to start of module linenums
   U32 linenumOffsetEnd;      // table offset that points to one location
                              //   beyond the last linenum of module
   SYM_DESCRIPTOR cachedModDescriptor; // cached module for adding and looking
                                       // up line numbers
   LOAD_STATE  linenumLoadState;   // state of loading linenums
   BOOLEAN  sorted;
   BOOLEAN  linenumSorted; //Hera 6/17/97
   LINENUM_STRUCT_TYPE previousLine; //linenum to be compared for duplicates
                                     // or whether sorted
   TABLE_OFFSET previousLinenumOffset;
   U16 linenums;     // count of how many linenums have been loaded for
                     // this module
   U32 modulesLoaded; // increment each time ::LinenumStart is called
public:

//------------------------------------------------------------------------
// LinenumTable() - constructor
//
// Purpose:
//    Initialize ordinal table variables for table creation and expansion.
//---------------------------------------------------------------------------
LinenumTable();    // constructor


//------------------------------------------------------------------------
// LinenumTable::ObliterateTable
//------------------------------------------------------------------------
VOID LinenumTable::ObliterateTable(VOID);


//------------------------------------------------------------------------
// LinenumTable::GetLinenumCount
//
// Purpose: Retrieve number of lines added
//          This value takes into account the number of modules loaded
//          and subtracts the extra linenum added at the end (whose purpose
//          is to hold the end address).
//------------------------------------------------------------------------
U32
LinenumTable::GetLinenumCount()  {
   return ((GetAvailMemOffset()/sizeof(LINENUM_STRUCT_TYPE))-1);
}

//------------------------------------------------------------------------
// LinenumTable::AddLinenum
//
// Purpose: insert line number into end of line number table (lt)
//------------------------------------------------------------------------
RETCODE
AddLinenum(LINENUM_STRUCT_TYPE& linenum);


//------------------------------------------------------------------------
// LinenumTable::GetLinenum
//
// Purpose: Retrieve line number information given a module descriptor
//          and requested line number.
//------------------------------------------------------------------------
RETCODE
GetLinenum(SYM_DESCRIPTOR     module,
           LINENUM_TYPE       requestedLinenum,
           DESCRIPTOR         addrRange,
           LINENUM_TYPE       *actualLinenum,
           COLUMN_TYPE        *actualColumn,
           LINENUM_DESCRIPTOR *nextIndex);

//------------------------------------------------------------------------
// LinenumTable::GetLastLinenum
//
// Purpose: Retrieve the last line number information given
//          a module descriptor.
//------------------------------------------------------------------------
RETCODE
GetLastLinenum(SYM_DESCRIPTOR     moduleDesc,
               DESCRIPTOR         lastLinenumAddr,
               LINENUM_TYPE       *lastLinenum);

//------------------------------------------------------------------------
// LinenumTable::GetLinenumInOrder
//
// Purpose: Retrieve line number information given a module descriptor
//          and requested line number.
//    NOTES: This routine implemented to fix PPR7517 and 7520.  Will be
//       removed when a new mixed mode data object implement.
//       This is private to Source Presenter only.
//------------------------------------------------------------------------
RETCODE
GetLinenumInOrder(SYM_DESCRIPTOR     module,
                  LINENUM_TYPE       requestedLinenum,
                  DESCRIPTOR         addrRange,
                  LINENUM_TYPE       *actualLinenum,
                  LINENUM_DESCRIPTOR *nextIndex);

//------------------------------------------------------------------------
// LinenumTable::GetRawLinenumByIndex
//
// Purpose: Retrieve basic linenum info given module and index
//------------------------------------------------------------------------
RETCODE
GetRawLinenumByIndex(SYM_DESCRIPTOR     module,
                     LINENUM_DESCRIPTOR index,
                     DESCRIPTOR         linenumAddr,
                     LINENUM_TYPE       *actualLinenum,
                     COLUMN_TYPE        *actualColumn,
                     LINENUM_DESCRIPTOR *nextIndex);


//------------------------------------------------------------------------
RETCODE
GetLinenumByIndex(SYM_DESCRIPTOR     module,
                  LINENUM_DESCRIPTOR index,
                  DESCRIPTOR         addrRangeDesc,
                  LINENUM_DESCRIPTOR *nextIndex,
                  LINENUM_TYPE       *linenum,
                  COLUMN_TYPE        *column);


//------------------------------------------------------------------------
RETCODE
LinenumTable::GetLinenumFirstLast(SYM_DESCRIPTOR module,
                                  LINENUM_TYPE  *firstLinenum,
                                  LINENUM_TYPE  *lastLinenum);

//------------------------------------------------------------------------
RETCODE
LinenumTable::GetLinenumFirstIndex(SYM_DESCRIPTOR         module,
                                   LINENUM_DESCRIPTOR FAR *nextIndex);


//------------------------------------------------------------------------
RETCODE
GetLinenumStmt(SYM_DESCRIPTOR     module,
               LINENUM_TYPE       requestedLinenum,
               COLUMN_TYPE        requestedColumn,
               DESCRIPTOR         addrRangeDesc,
               LINENUM_TYPE       *actualLinenum,
               COLUMN_RANGE_TYPE  *actualColumnRange,
               LINENUM_DESCRIPTOR *nextIndex);


//------------------------------------------------------------------------
RETCODE
GetLinenumStmtByIndex(SYM_DESCRIPTOR     module,
                      LINENUM_DESCRIPTOR index,
                      DESCRIPTOR         addrRangeDesc,
                      LINENUM_TYPE       *linenum,
                      COLUMN_RANGE_TYPE  *columnRange,
                      LINENUM_DESCRIPTOR *nextIndex);


//------------------------------------------------------------------------
// LinenumTable::LinenumEnd
//
// Purpose: Completes, or closes, the addition of line numbers to selected
//          module
//------------------------------------------------------------------------
RETCODE
LinenumEnd(void);


//------------------------------------------------------------------------
// LinenumTable::LinenumStart
//
// Purpose: Starts (i.e. opens) the addition of line numbers to selected
//          module
//------------------------------------------------------------------------
RETCODE
LinenumStart(SYM_DESCRIPTOR moduleDescriptor);


//------------------------------------------------------------------------
// LinenumTable::MapAddr2Linenum
//
// Purpose: Given an address and module descriptor, look up line number
//          that contains the requested address
//------------------------------------------------------------------------
RETCODE
MapAddr2Linenum(SYM_LINE_TYPE      lineType,
		U16                segment,
                OFFSET_ADDR_TYPE   requestedAddr,
                SYM_DESCRIPTOR     module,
                LINENUM_TYPE       *linenum,
                COLUMN_RANGE_TYPE  *column,
                DESCRIPTOR         addrRange,
                LINENUM_DESCRIPTOR *index);

//------------------------------------------------------------------------
// LinenumTable::UpdateCacheParams
//
// Purpose: Fills in cached module descriptor and start and end offsets
//------------------------------------------------------------------------
RETCODE
LinenumTable::UpdateCacheParams(SYM_DESCRIPTOR module);

//------------------------------------------------------------------------
// LinenumTable::GetLineNumbersList
//
// Purpose: Retrieve a list of line numbers of <module>, started from
// <startIndex>.  Fill the descriptor in <linenumList> return the actual
// returned descriptor, excluding the <startIndex>, Stop if reach the
// <numRequested> lines.
//------------------------------------------------------------------------
RETCODE
GetLineNumbersList(SYM_DESCRIPTOR          module,
                   LINENUM_DESCRIPTOR      startIndex,
                   U16                     numRequested,
                   LINENUM_DESCRIPTOR FAR* linenumList,
                   U16 FAR*                actualReturned);


};  // end of class LinenumTable

#endif

//------------------------------------------------------------------------
// LinenumCompare
//
// Purpose:
//    Provides the compare function for the QSort sort of linenums
//------------------------------------------------------------------------
int LinenumCompare(const void _FAR *first,
                   const void _FAR *second);
int LinenumCompare1(const void _FAR *first,
		   const void _FAR *second);
//------------------------------------------------------------------------
// UpdateLinenumEndAddr
//
// Purpose: Updates the dummy address to the value passed in.  This is
//          called when the module range is updated from SymAddSymbolSetAddr
//
// Input parameters:
//    symPtr: pointer to module object
//    endAddr: address to fill in to last (dummy) linenum
// 
// Error:
//------------------------------------------------------------------------
RETCODE
UpdateLinenumEndAddr(SYM_TYPE_MODULE HUGE *modulePtr,
                     U32                   endAddr);


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