/* RECALLABLE_DTR */

/* This is a program based on Dana Schwartz's program that uses SMG and
    callable Datatrieve to obtain command line recall within Datatrieve.
    It replaces the "stub" or server task DTR32.
    I wrote this because: I needed to learn "C" better, and because
    people have been requesting the Datatrieve call interface to be
    documented in "C".  This doesn't really replace having DEC support
    an interface, but it's a reasonable interim solution.

    There are ABSOLUTELY NO warranties on these examples, and no
    commitment to fix errors.  However, if anyone does come
    across an error and has a fix for it, I'd like to know about
    it so I can send out a correction on the next tape.

    Bart Z. Lederman
    2572 E. 22nd St.
    Sheepshead Bay, NY 11235-2504   */

#include "dab.h"	/* private Datatrieve Access Block definition */
#include <smgdef.h>	/* DEC definitions for SMG */
#include <descrip.h>	/* DEC definitions for string descriptors */
#include <stdio.h>

long unsigned int

    keyboard,
    table,
    init_options = DTR$K_SEMI_COLON_OPT | DTR$K_UNQUOTED_LIT |
			DTR$K_SYNTAX_PROMPT,
    options = DTR$M_OPT_CONTROL_C | DTR$M_OPT_STARTUP |
		DTR$M_OPT_FOREIGN | DTR$M_OPT_BANNER  | DTR$M_OPT_CMD ;

int hundred = 100,  /* probably could be a literal */
    dtr_status;

short unsigned int

    term = SMG$K_TRM_CR;


char
    line[255],		/* need large buffers for 132 column operation */
    msg_buffer[132],	/* DEC default buffers (in DAB.H) are o.k. for */
    aux_buffer[132];	/* 80 column operation */

$DESCRIPTOR(line_desc, line);	    /* some calls need descriptors */
$DESCRIPTOR(msg_desc, msg_buffer);
$DESCRIPTOR(aux_desc, aux_buffer);

int DTR$DTR();		/* externally referenced function */

/* extern DTR$_EXIT;	this is supposed to be defined when the program
			is linked but for some reason I can't get it
			to come out right. So... */

#define DTR$_EXIT 9276601

main()

{

/* initialize SMG with a virtual keyboard and keybord table (pretty
    standard stuff). */

    SMG$CREATE_VIRTUAL_KEYBOARD ( &keyboard, 0 , 0 , 0 , 0);
    SMG$CREATE_KEY_TABLE ( &table);

/* initialize Datatrieve */

    DTR$INIT ( &DAB, &hundred, &msg_desc, &aux_desc, &init_options );

/* call DTR$DTR to let it write out what it wants to, and check status */

    dtr_status = DTR$DTR ( &DAB, &options );

/* the following loop is performed until the user enters a Control-Z,
    or says "EXIT" to DTR (which will return an exit status). */

    while ( ( dtr_status != DTR$_EXIT )  &&
	    (       term != SMG$K_TRM_CTRLZ )  ) {

/* We must get the length of the prompt returned by DTR so that
    SMG will know how much to write on the screen */

	msg_desc.dsc$w_length = DAB.DAB$W_MSG_LEN;

/* Prompt the user and retrieve a command line (DTR has put the prompt
    into msg_buffer) */

	SMG$READ_COMPOSED_LINE ( &keyboard, &table,
	    &line_desc,
	    &msg_desc,
	    0,			/* don't bother with record length */
	    0, 0, 0, 0, 0, 0, 
	    &term );

/* pass the command line to Datatrieve */

	DTR$COMMAND ( &DAB, &line_desc );

/* Let DTR write out (whatever) and return status */

	dtr_status = DTR$DTR ( &DAB, &options );

	};

/* All done, clean things up before leaving */

    DTR$FINISH ( &DAB );
}

