#pragma extend

#define  RMXRET  int
#define  RMXOBJ  int
#include <rmx.h>

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stddef.h>

#define  FALSE   0
#define  TRUE    ~FALSE

int      ci_tkn, co_tkn, cmd_tkn, status, cmd_status, aux_status, index,
         done, using_tty;
char     cmds[256], tmp[50], *res, *this, *next;

EXCP_HANDLER_ATTRIBS excp_info;

/****************************************************************************/
/* explain_ccode - outputs explanation of erroneous condition code          */
/****************************************************************************/

const char whilel[]  = "while loading command";
const char whilee[]  = "while executing command";

void explain_ccode( int ccode, const char *msg )
    {
    tmp[0] = 0;
    rqcformatexception( tmp, 50, ccode, 1, &aux_status );

    if ( aux_status != E_OK )
        sprintf( tmp, "%04X: E$UNKNOWN$EXCEPTION", ccode );
    else
        (void)cstr( tmp, tmp );

    printf( "\n%s, %s\n", tmp, msg );
    }

/****************************************************************************/
/* execcmd - execute a single command                                       */
/****************************************************************************/

void execcmd( char *cmd )
    {
    udistr( cmd, cmd );    
    rqcsendcommand( cmd_tkn, cmd, &cmd_status, &status );

    if ( ( status != E_OK ) && ( status != E_CONTINUED ) )
        if ( status == E_FNEXIST )
            printf( "command not found\n" );
        else
            explain_ccode( status, whilel );
    
    if ( cmd_status != E_OK )
        explain_ccode( cmd_status, whilee );
    }
                    
/****************************************************************************/
/* execcmds - executes command(s) specified in command string. Multiple     */
/* commands are separated by '!' character.                                 */
/****************************************************************************/

void execcmds( void )
    {
    this = cmds;

    while ( ( next = strchr( this, '!' ) ) != NULL )
        {
        *next++ = '\0';
        execcmd( this );
        this = next;
        }
    
    execcmd( this );
    }

/****************************************************************************/
/* main                                                                     */
/****************************************************************************/

int main( int argc, char *argv[] )
    {
    /* set up so that exceptional conditions do not destroy us */

    excp_info.mode = NO_EXCEPTIONS;
    rqsetexceptionhandler( excp_info, &status );

    /* obtain a connection for delivering commands to Human Interface */
    
    ci_tkn = rqcgetinputconnection( CONSOLE_INPUT_DEVICE, &status );

    if ( status == E_OK )
        co_tkn = rqcgetoutputconnection( CONSOLE_OUTPUT_DEVICE, OVER_PREPOSITION, &status );
    
    if ( status == E_OK )
        cmd_tkn = rqccreatecommandconnection( ci_tkn, co_tkn, 0, &status );
    
    if ( status != E_OK )
        {
        explain_ccode( status, whilee );
        exit( status );
        }

    /* if command(s) were specified on command line, execute them */

    if ( argc != 1 )
        {
         strcpy( cmds, argv[1] );
        
         for ( index = 2; index < argc; index++ )
            {
            if ( ( strlen( cmds ) + strlen( argv[index] ) + 2 ) > sizeof( cmds ) )
                {
                strcat( cmds, " &" );
                execcmds();
                strcpy( cmds, argv[index] );
                }
            else
                {
                strcat( cmds, " " );
                strcat( cmds, argv[index] );
                }
            }

        execcmds();
        }
    
    /* otherwise, prompt for and execute commands until an empty one is seen */
    
    else
        {
        if ( isatty( fileno( stdin ) ) )
            printf( "\nCommand 'EXIT' terminates EXEC.\n\n" );
            
        done = FALSE;
        
        while ( !done )
            {
            if ( status == E_CONTINUED )
                printf( "\r**" );
            else
                printf( "\r> " );

            res = gets( cmds );
            
            if ( res == NULL )
                {
                puts( "<EOF>" );
                done = TRUE;
                }
            else
                {
                if ( !isatty( fileno( stdin ) ) )
                    puts( cmds );
          
                if ( ( strcmpi( cmds, "exit" ) == 0 ) && ( status != E_CONTINUED ) )
                    done = TRUE;
                else
                    execcmds();
                }
            }
        }

    exit( E_OK );
    }
