#include <ctype.h>
#include <time.h>
#include "globals.h"
#include "memalloc.h"
#include "parser.h"
#include "input.h"
#include "tokenize.h"
#include "segment.h"
#include "assume.h"
#include "proc.h"
#include "expreval.h"
#include "extern.h"
#include "fastpass.h"
#include "msgtext.h"
#include "myassert.h"
#include "linnum.h"
#include "omf.h"
extern struct qdesc LinnumQueue;
extern int procidx;
static struct asym *dmyproc;
static uint_32 lastLineNumber;
static void AddLinnumData( struct line_num_info *data )
{
struct qdesc *q = NULL;
if ( Options.output_format == OFORMAT_COFF ) {
q = (struct qdesc *)CurrSeg->e.seginfo->LinnumQueue;
if ( q == NULL ) {
q = LclAlloc( sizeof( struct qdesc ) );
CurrSeg->e.seginfo->LinnumQueue = q;
q->head = NULL;
}
} else
q = &LinnumQueue;
data->next = NULL;
if (q != NULL)
{
if (q->head == NULL)
q->head = q->tail = data;
else {
((struct line_num_info *)q->tail)->next = data;
q->tail = data;
}
}
}
void AddLinnumDataRef( unsigned srcfile, uint_32 line_num )
{
struct line_num_info *curr;
if ( Options.output_format == OFORMAT_COFF && Options.debug_symbols != 4 &&
CurrProc == NULL &&
( dmyproc == NULL ||
dmyproc->debuginfo->file != srcfile ||
dmyproc->segment != (struct asym *)CurrSeg ) ) {
char procname[12];
if ( dmyproc ) {
dmyproc->total_size =
((struct dsym *)dmyproc->segment)->e.seginfo->current_loc -
dmyproc->offset;
}
sprintf( procname, "$$$%05u", procidx );
dmyproc = SymSearch( procname );
if ( dmyproc == NULL ) {
dmyproc = CreateProc( NULL, procname, SYM_INTERNAL );
dmyproc->isproc = TRUE;
dmyproc->included = TRUE;
AddPublicData( dmyproc );
} else
procidx++;
if ( dmyproc->isproc == TRUE ) {
SetSymSegOfs( dmyproc );
dmyproc->Ofssize = ModuleInfo.Ofssize;
dmyproc->langtype = ModuleInfo.langtype;
if ( write_to_file == TRUE ) {
curr = (struct line_num_info *)LclAlloc(sizeof(struct line_num_info));
curr->sym = dmyproc;
curr->line_number = GetLineNumber();
curr->file = srcfile;
curr->number = 0;
AddLinnumData( curr );
}
}
}
if( line_num && ( write_to_file == FALSE || lastLineNumber == line_num )) {
return;
}
curr = (struct line_num_info *)LclAlloc(sizeof(struct line_num_info));
curr->number = line_num;
if ( line_num == 0 ) {
if ( Parse_Pass == PASS_1 &&
Options.output_format == OFORMAT_COFF && CurrProc && CurrProc->sym.ispublic == FALSE ) {
CurrProc->sym.included = TRUE;
AddPublicData( (struct asym *)CurrProc );
}
curr->sym = ( CurrProc ? (struct asym *)CurrProc : dmyproc );
curr->line_number = GetLineNumber();
if (CurrProc->e.procinfo->size_prolog == 0 && Parse_Pass)
curr->line_number -= 3;
curr->file = srcfile;
if ( dmyproc ) {
dmyproc->total_size =
((struct dsym *)dmyproc->segment)->e.seginfo->current_loc -
dmyproc->offset;
dmyproc = NULL;
}
if ( CurrProc && CurrProc->e.procinfo->size_prolog ) {
AddLinnumData( curr );
curr = LclAlloc( sizeof( struct line_num_info ) );
curr->number = GetLineNumber();
curr->offset = GetCurrOffset();
curr->srcfile = srcfile;
}
} else {
curr->offset = GetCurrOffset();
curr->srcfile = srcfile;
}
lastLineNumber = line_num;
if ( Options.output_format == OFORMAT_OMF )
omf_check_flush( curr );
if ( CurrSeg->e.seginfo->linnum_init == FALSE ) {
CurrSeg->e.seginfo->linnum_init = TRUE;
if ( TypeFromClassName( CurrSeg, CurrSeg->e.seginfo->clsym ) != SEGTYPE_CODE ) {
EmitWarn( 2, LINNUM_INFO_FOR_SEGMENT_WITHOUT_CLASS_CODE, CurrSeg->sym.name );
}
}
AddLinnumData( curr );
return;
}
void QueueDeleteLinnum( struct qdesc *queue )
{
struct line_num_info *curr;
struct line_num_info *next = NULL;
if ( queue == NULL )
return;
curr = queue->head;
for( ; curr ; curr = next ) {
if (next){
next = curr->next;
LclFree(curr);
}
}
return;
}
void LinnumFini( void )
{
if ( dmyproc ) {
dmyproc->total_size =
((struct dsym *)dmyproc->segment)->e.seginfo->current_loc -
dmyproc->offset;
}
}
void LinnumInit( void )
{
lastLineNumber = 0;
dmyproc = NULL;
}