
/***************************************************************************
**
**    $Header$
**
**    $Log$
** 
****************************************************************************/

/*----------------------------------------------------------------------------
** Name: linenum.h
**
** Title: Line Number Table
**
** Purpose:
**  Classes and methods declarations for managing the line numbers
**
** Status: PRELIMINARY
**
** $Log$
** 
** $Header:   D:/EPSLDV1/SRC/LOG/LINENUM.H__   1.7.1.0.1.0   11 Nov 1996 12:58:08   ZJRD  $
**
** Copyright (C) 1995 Microtek International.  All rights reserved.
**
**--------------------------------------------------------------------------*/

#ifndef _LINENUM_

#include "sympool.h"
#include "symblsvr.h"
#include "symmgr.h"
#include "symutil.h"


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

typedef U32 LINENUM_INDEX;

typedef struct {
   OFFSET_ADDR_TYPE  addr;    /* logical address of linenum */
   LINENUM_TYPE      linenum; /* integer value of line number */
   COLUMN_TYPE       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;
   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)) - 
            modulesLoaded);
}

//------------------------------------------------------------------------
// 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,
           ADDR_RANGE_TYPE    *addrRange,
           LINENUM_TYPE       *actualLinenum,
           COLUMN_TYPE        *actualColumn,
           LINENUM_DESCRIPTOR *nextIndex);

//------------------------------------------------------------------------
// 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,
                  ADDR_RANGE_TYPE    *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,
                     OFFSET_ADDR_TYPE   *linenumAddr,
                     LINENUM_TYPE       *actualLinenum,
                     COLUMN_TYPE        *actualColumn,
                     LINENUM_DESCRIPTOR *nextIndex);


//------------------------------------------------------------------------
RETCODE
GetLinenumByIndex(SYM_DESCRIPTOR     module,
                  LINENUM_DESCRIPTOR index,
                  ADDR_RANGE_TYPE    *addrRange,
                  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,
               ADDR_RANGE_TYPE    *addrRange,
               LINENUM_TYPE       *actualLinenum,
               COLUMN_RANGE_TYPE  *actualColumnRange,
               LINENUM_DESCRIPTOR *nextIndex);


//------------------------------------------------------------------------
RETCODE
GetLinenumStmtByIndex(SYM_DESCRIPTOR     module,
                      LINENUM_DESCRIPTOR index,
                      ADDR_RANGE_TYPE    *addrRange,
                      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,
                OFFSET_ADDR_TYPE   requestedAddr,
                SYM_DESCRIPTOR     module,
                LINENUM_TYPE       *linenum,
                COLUMN_RANGE_TYPE  *column,
                ADDR_RANGE_TYPE    *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);

//------------------------------------------------------------------------
// 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);


#define _LINENUM_
#endif
/******************************** E O F *************************************/
