
/* lexer_dbg.c - DEBUG INCLUDE ONLY */
#include "sprtf.c"

static tmbstr tidydbg_TokenSource( TidyDocImpl* doc, GetTokenMode mode )
{
    Lexer* lexer = doc->lexer;

    if (lexer->pushed || lexer->itoken)
    {
        /* Deal with previously returned duplicate inline token */
        if (lexer->itoken)
        {
            /* itoken rejected */
            if (lexer->pushed)
            {
                /* lexer->pushed = no;
                return lexer->itoken; */
               return "itoken pushed";
            }
            /* itoken has been accepted 
            lexer->itoken = NULL; */
        }
            
        /* duplicate inlines in preference to pushed text nodes when appropriate
        lexer->pushed = no; */
        if (lexer->token->type != TextNode
            || !(lexer->insert || lexer->inode))
            return "lexer->token"; /* lexer->token */

        return "itoken:InsertedToken"; /* lexer->itoken = TY_(InsertedToken)( doc ); */
    }

    /* assert( !(lexer->pushed || lexer->itoken) ); */

    /* at start of block elements, unclosed inline
       elements are inserted into the token stream */
    if (lexer->insert || lexer->inode)
       return "token:InsertedToken";   /* lexer->token = TY_(InsertedToken)( doc ); */

    if (mode == CdataContent)
    {
        /* assert( lexer->parent != NULL );
        return GetCDATA(doc, lexer->parent); */
       return "GetCDATA";
    }

    return "FromStream";   /* GetTokenFromStream( doc, mode ); */
}

Node* tidydbg_GetToken( TidyDocImpl* doc, GetTokenMode mode )
{
    Lexer* lexer = doc->lexer;

    if (lexer->pushed || lexer->itoken)
    {
        /* Deal with previously returned duplicate inline token */
        if (lexer->itoken)
        {
            /* itoken rejected */
            if (lexer->pushed)
            {
                lexer->pushed = no;
                return lexer->itoken;
            }
            /* itoken has been accepted */
            lexer->itoken = NULL;
        }
            
        /* duplicate inlines in preference to pushed text nodes when appropriate */
        lexer->pushed = no;
        if (lexer->token->type != TextNode
            || !(lexer->insert || lexer->inode))
            return lexer->token;
        return lexer->itoken = TY_(InsertedToken)( doc );
    }

    assert( !(lexer->pushed || lexer->itoken) );

    /* at start of block elements, unclosed inline
       elements are inserted into the token stream */
    if (lexer->insert || lexer->inode)
        return lexer->token = TY_(InsertedToken)( doc );

    if (mode == CdataContent)
    {
        assert( lexer->parent != NULL );
        return GetCDATA(doc, lexer->parent);
    }

    return GetTokenFromStream( doc, mode );
}

void  debug_stop( void )
{
   int   i;
   i = 0;
}

#define  MX_SHORT_TEXT  64
static tmbstr Get_Short_Text( TidyDocImpl* doc, Node* node )
{
   static tmbchar _s_stbuf[(MX_SHORT_TEXT*2)+4];
   tmbstr tb = _s_stbuf;
   uint start = node->start;
   uint end = node->end;
   uint ix;
   byte c = 0;
   uint len = end - start;

   *tb = 0;
   if( len > MX_SHORT_TEXT )
   {
      end = start + MX_SHORT_TEXT - 4;
      /* strcat(tb,"=long text="); */
   }
   {
      len = 0;
      tb[len++] = '=';
      for ( ix = start; ix < end; ++ix )
      {
         c = (byte) doc->lexer->lexbuf[ix];
         if( c < ' ' ) {
            tb[len++] = '^';
            c += '@';
         }
         tb[len++] = c;
      }
      if( len > MX_SHORT_TEXT )
      {
         tb[len] = 0;
         strcat(tb,"...");
      }
      else
      {
         tb[len++] = '=';
         tb[len] = 0;
      }
   }
   return tb;
}

tmbstr Get_Node_Type( Node * node )
{
   static tmbchar _s_ntbuf[32];
   tmbstr ntb = _s_ntbuf;
   tmbstr nt = "<uncased>";
   switch ( node->type )
   {
   case RootNode:    nt = "RootNode"; break;
   case DocTypeTag:  nt = "DocTypeTag"; break;
   case CommentTag:  nt = "CommentTag"; break;
   case XmlDecl:     nt = "XmlDecl"; break;
   case ProcInsTag:  nt = "ProcInsTag"; break;
   case TextNode:    nt = "TextNode"; break;
   case CDATATag:    nt = "CDATATag"; break;
   case SectionTag:  nt = "SectionTag"; break;
   case AspTag:      nt = "AspTag"; break;
   case JsteTag:     nt = "JsteTag"; break;
   case PhpTag:      nt = "PhpTag"; break;
   case StartTag:    nt = "StartTag"; break;
   case EndTag:      nt = "EndTag"; break;
   case StartEndTag: nt = "StartEndTag"; break;
   }
   strcpy(ntb,nt);
   while(strlen(ntb) < 12){ strcat(ntb," "); }
   return ntb;
}

int Is_Text_Type_Node( Node * node )
{
   switch ( node->type )
   {
   case TextNode:
   case CDATATag:
   case SectionTag:
   case AspTag:
   case JsteTag:
   case PhpTag:
      return yes;
   }
   return no;
}

static int stop_here(void)
{
    int i;
    i = 0;
    return i;
}

/* Show node - output some aspects of the node fetched ... */
void tidydbg_ShowNode( TidyDocImpl* doc, Node* node, tmbstr src )
{
   if( node )
   {
       TidyNode tnod = (TidyNode)node;
       uint line = tidyNodeLine(tnod);
       uint colm = tidyNodeColumn(tnod);

      tmbstr nt = Get_Node_Type( node );
      tmbstr fmt = "%s = <%s%s>, src=%s";

      if( !last_was_crlf )
          sprtf("\n");
#ifdef TIDY_STORE_ORIGINAL_TEXT
      if (node->otext) {
          sprtf("OTEXT:[%s]\n", node->otext);
          if( strcmp(node->otext,"<p>") == 0 )
              stop_here();
      }
#endif

      sprtf("%3d:%3d: ", line, colm);

      if(!src) /* if NO src, then modify FORMAT string */
         fmt = "%s = <%s%s>";
         
      /* give an OUTPUT */
      sprtf( fmt,
         nt,
         ( (node->type == EndTag) ? "/" : "" ),
         ( node->element ? node->element :
         ( Is_Text_Type_Node(node ) ? Get_Short_Text(doc,node) : 
         "=blank=") ),
         (src ? src : "???") );

      if( node->implicit)
          sprtf( " (implicit)" );

      sprtf("\n");  /* end of line */

      if( node->element && (TY_(tmbstrcasecmp)(node->element,"script") == 0) )
         debug_stop();

   }
   else
   {
      sprtf( "NULL node ... ... ... ... src=%s\n", 
         (src ? src : "???") );
   }
}

Node* TY_(GetToken)( TidyDocImpl* doc, GetTokenMode mode )
{
   tmbstr src = tidydbg_TokenSource( doc, mode );
   Node * node = tidydbg_GetToken( doc, mode );
   tidydbg_ShowNode( doc, node, src );
   return node;
}

/* eof - lexer-dbg.c - DEBUG INCLUDE ONLY */