/* l2xiidbg.c  LTX2X interpreter debugging routines for interpreter code */
/*  Written by: Peter Wilson, CUA  [email protected]                */

#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 */
/********************************************************************/



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



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