//
//  Copyright (C) 1997,1998,1999 Forest Edge Software, see License.txt for Rights
//
//  Program:    eVAX, a "Virtual VAX" for Mac OS and other computers
//
//  Author:     Tom Cole
//
//  Module:     console_dispatch.c
//
//  Purpose:    This routine accepts a single console command as an ASCIZ string,
//              decodes it, and runs the correct dispatcher.  It assumes that the
//              command has been correctly uppercased and contains only a single
//              command (no ';' allowed).
//
//  History:    07/28/97    New header format standardization
//
//              11/16/99    Added support for DCL-based parsing and dispatch.
//

#include "vax.pch"
#include "console_proto.h"
#include "asmproto.h"
#include "dclrtl.h"

extern struct CONSOLE_DISPATCH_TABLE console_dispatch_table[];


//  Execute a console command

LONGWORD console_dispatch( char * cmd )
{
    LONGWORD rc;
    char *p;
    LONGWORD verb;
    LONGWORD n;
    console_handler routine;
    
    static char dispatcher_initialized = 0;

    if( !dispatcher_initialized ) {
        console_dispatch_init();
        dispatcher_initialized = 1;
    }
    
    
    /* vax = *Vax;  -- now use global vax */
    p = cmd;
    rc = VAX_OK;

    if( vax && vax-> console.assembler_mode ) {
        rc = assemble( &p );
        return rc;
    }
    
    //  Read verb (must be unambigious in first 4 bytes
    
    read_verb( &p, &verb );
    
    //  Find what command this is to dispatch
    
    routine = 0L;
    for( n = 0; console_dispatch_table[ n ].handler; n++ ) {
    
        if( console_dispatch_table[ n ].verb[ 0 ] == verb ||
            console_dispatch_table[ n ].verb[ 1 ] == verb ||
            console_dispatch_table[ n ].verb[ 2 ] == verb ) {
                routine = console_dispatch_table[ n ].handler;
                if( ( long ) routine == -1L ) {
                    routine = 0L;
                    break;
                }
                    
                rc = (*routine)( &p );
                break;
            }
    }
    
    if( routine == 0L ) 
        rc = VAX_UNKCMD;

    if( rc == VAX_OK ) {
        flush_blanks( &p );
        if( !isend( *p )) 
            rc = VAX_EXTRACMD;
    }
    
    //  If we didn't already figure out (and handle) the command, then
    //  let's try the DCL parse gadget.  If it parses okay, then dispatch
    //  the command!
    
    if( routine == 0L ) {
    
        if( vax-> debug & DBG_DCL )
            DCLsetdebug( 2, 0 );
            
        rc = DCLparse( "evax", cmd, DCL_INPUT );
        
        if( !DCLERROR( rc )) {
            rc = DCLdispatch();
        }
        else
            rc = VAX_SYNTAX;
            
        DCLreset();

        DCLsetdebug( 0, 0 );
        
    
    }
    
    return rc;
}

