/* l2xiidbg.c  LTX2X interpreter debugging routines for interpreter code */
/*  Written by: Peter Wilson, CUA  pwilson@cme.nist.gov                */

#include <stdio.h>
#include "l2xicmon.h"
#include "l2xiscan.h"
#include "l2xisymt.h"
#include "l2xiexec.h"
#include "l2xiidbg.h"

/* EXTERNALS */

/* extern FILE *fcodeseg; */      /* code segment o/p file */

/* GLOBALS */

char dbuff[256];           /* a character buffer for internal use */
int dlindent = 2;            /* line indentation */
int PLEVEL = 0;            /* routine nesting level */
char dbuffer[256];         /* character buffer for external use */

/********************************************************************/
/* debug_print(s)    prints a debugging string                      */

debug_print(s)
char s[];
{
  if (DEBUG <= 0) return;

  fprintf(stderr, "%s", s);
  fflush(stderr);
  fprintf(ferr, "%s", s);
  fflush(ferr);
}                                                /* end debug_print */
/********************************************************************/



/********************************************************************/
/* log_print(s)    prints a string to the log(s)                    */

log_print(s)
char s[];
{

  fprintf(stderr, "%s", s);
  fflush(stderr);
  fprintf(ferr, "%s", s);
  fflush(ferr);
}                                                  /* end log_print */
/********************************************************************/



/********************************************************************/
/* entry_debug(s)     prints the name of a routine at entry         */        

entry_debug(s)
char s[];               /* name of the routine */
{
  if (DEBUG < Dtrace) return;

  PLEVEL++;             /* increase the nesting level */
  sprintf(dbuff, "%*s Entering: %s\n", PLEVEL*dlindent, " ", s);
  debug_print(dbuff);

}                                                /* end entry_debug */
/********************************************************************/


/********************************************************************/
/* exit_debug(s)     prints the name of a routine at exit           */        

exit_debug(s)
char s[];               /* name of the routine */
{
  if (DEBUG < Dtrace) return;

  sprintf(dbuff, "%*s Exiting: %s\n", PLEVEL*dlindent, " ", s);
  debug_print(dbuff);
  PLEVEL--;             /* decrement the nesting level */

}                                                /* end entry_debug */
/********************************************************************/



/********************************************************************/
/* code_segment_debug()  Prints a code segment                      */

code_segment_debug(code_segment, limit)
int *code_segment;
int *limit;

{
  int i = 0;
  SYMTAB_NODE_PTR sp;
  int cp;

/*  if (DEBUG < Dbasic) return; */
  
  sprintf(dbuff, "\n   CREATED CODE_SEGMENT\n");
  if (DEBUG >= Dbasic) debug_print(dbuff);
  fprintf(fcodeseg, "%s", dbuff);
  while (code_segment != limit) {
    cp = (int) *code_segment;
    if (cp == STATEMENT_MARKER) {     /* a statement marker */
      sprintf(dbuff, "%d   %d   %d    %s\n", 
         code_segment, i, cp, "<statement_marker>");
      if (DEBUG >= Dbasic) debug_print(dbuff);
      fprintf(fcodeseg, "%s", dbuff);
      *code_segment++;
      i++;
      cp = (int) *code_segment;
      sprintf(dbuff, "%d   %d   %d    %s\n", 
         code_segment, i, cp, "<the line number>");
      if (DEBUG >= Dbasic) debug_print(dbuff);
      fprintf(fcodeseg, "%s", dbuff);
    }
    else if (cp == ADDRESS_MARKER) {   /* an address marker */
      sprintf(dbuff, "%d   %d   %d    %s\n", 
         code_segment, i, cp, "<address_marker>");
      if (DEBUG >= Dbasic) debug_print(dbuff);
      fprintf(fcodeseg, "%s", dbuff);
      *code_segment++;
      i++;
      cp = (int) *code_segment;
      sprintf(dbuff, "%d   %d   %d    %s\n", 
         code_segment, i, cp, "<the address>");
      if (DEBUG >= Dbasic) debug_print(dbuff);
      fprintf(fcodeseg, "%s", dbuff);
    }
    else if (tok_code_to_str(cp) != NULL) {            /* a token code */
      sprintf(dbuff, "%d   %d   %d    %s\n", 
         code_segment, i, cp, tok_code_to_str(cp));
      if (DEBUG >= Dbasic) debug_print(dbuff);
      fprintf(fcodeseg, "%s", dbuff);
    }
    else {                                /* should be a symtab node ptr */
      sprintf(dbuff, "%d   %d   %d",
         code_segment, i, cp);
      if (DEBUG >= Dbasic) debug_print(dbuff);
      fprintf(fcodeseg, "%s", dbuff);
      fflush(fcodeseg);
      if (cp <= 0) {        /* REAL PROBLEM */
        sprintf(dbuff, "   <Possible problem: value out of range!>\n");
        if (DEBUG >= Dbasic) debug_print(dbuff);
        fprintf(fcodeseg, "%s", dbuff);
      }
      else {
        sp = (SYMTAB_NODE_PTR) cp;
        sprintf(dbuff, "    %s\n", 
                sp->name);
        if (DEBUG >= Dbasic) debug_print(dbuff);
        fprintf(fcodeseg, "%s", dbuff);
      }
    }

    *code_segment++;
    i++;
  }  /* end while */

  sprintf(dbuff, "\nFinished printing the code segment\n");
  if (DEBUG >= Dbasic) debug_print(dbuff);
  fprintf(fcodeseg, "%s", dbuff);
  fflush(fcodeseg);


}                                         /* end code_segment_debug */
/********************************************************************/


/********************************************************************/
/* code_segment_entry_debug()  Prints an entry in a code segment    */

code_segment_entry_debug(code_entry)
int *code_entry;
{
  int cp;

  if (DEBUG < Dbasic) return;
  
    cp = (int) *code_entry;
    if (STATEMENT_MARKER == cp) {     /* a statement marker */
      sprintf(dbuff, "%d   %d    %s\n", 
         code_entry, cp, "<statement_marker>");
  debug_print(dbuff);
  return;
    }
    else if (ADDRESS_MARKER == cp) {   /* an address marker */
      sprintf(dbuff, "%d   %d    %s\n", 
         code_entry, cp, "<address_marker>");
  debug_print(dbuff);
  return;
    }
    else if (tok_code_to_str(cp) != NULL) {            /* a token code */
      sprintf(dbuff, "%d   %d    %s\n", 
         code_entry, cp, tok_code_to_str(cp));
  debug_print(dbuff);
  return;
    }
    else {                    /* should be an address of some sort */
      sprintf(dbuff, "%d   %d    %s\n",
         code_entry, cp, "<an address>");  
  debug_print(dbuff);
  return;
    }
}                                   /* end code_segment_entry_debug */
/********************************************************************/


/********************************************************************/
/* scan_source_debug()    Print current state of source buffer      */

extern int ch;                  /* current input character */
extern char source_buffer[];    /* the source buffer */
extern int buffer_offset;       /* char offset into source buffer */
extern char *bufferp;           /* source buffer ptr */

scan_source_debug()
{

  if (DEBUG < Dscan) return;
  
  sprintf(dbuff, "Source line      : %s", source_buffer);
  debug_print(dbuff);
  debug_print("\n");
/*  sprintf(dbuff, "Source line state: %c ^ %s", ch, bufferp); */
  sprintf(dbuff, "Source line state: ");
  debug_print(dbuff);
  sprintf(dbuff, "%c", ch);
  debug_print(dbuff);
  debug_print("^");
  sprintf(dbuff, "%s", bufferp);
  debug_print(dbuff);
  debug_print("\n");

}                                          /* end scan_source_debug */
/********************************************************************/



/********************************************************************/
/* scan_token_debug()     Print info about current token            */

extern TOKEN_CODE token;        /* current token code */
extern char *tokenp;            /* token string ptr */
extern char token_string[];     /* token string */

scan_token_debug()
{

  if (DEBUG < Dscan) return;
  
  sprintf(dbuff, "Token code: %d ; token string: %s\n", 
                  token, token_string);
  debug_print(dbuff);

}                                           /* end scan_token_debug */
/********************************************************************/



/********************************************************************/



/********************************************************************/



