/* This file contains the routines needed to immplement DDT scripts.
 */

#ifdef DDTSCRIPT

#ifndef	DDTCAT	/* Don't reget hdrs if catting when all routines internal */
#include	<pdefs.h>
#include	<ptypes.h>
#include	"mdep.h"
#include	"ddt.h"

ext char d_crlf[];
#endif

#define MAXSCRIPTLEN 256
intern char script_string[MAXSCRIPTLEN];
intern intf script_valid = 0;
intern char *scriptp = 0;

/* Figure out what script command to do and do it.  Currently this is
 * just to create or delete a script depending on whether one or two
 * ESC's.
 */
intern retcd d_doscriptcmd(dsp)
reg ddtst *dsp;
{
    retcd d_read_string();

    if (dsp->d_inpst == S_TESC)
      script_valid = 0;
    else {
	dsp->d_puts(" Enter script:");
	dsp->d_puts(d_crlf);
	if (d_read_string(dsp, script_string, MAXSCRIPTLEN, '\0') == ERR)
	  return ERR;
	script_valid = 1;
    }
    return OK;
}

/* Set scriptp to point to the script string that should be executed.
 * d_getc() notices this and does the right thing.
 */
intern d_read_from_script()
{
    if (script_valid)
      scriptp = script_string;
}

static intf condition_flag = 0;

/* Sets the condition flag appropritately.  If not executing from a
 * script, print result of test.
 */
intern retcd d_set_condition(dsp)
reg ddtst *dsp;
{
    intw val1, val2;
    char tst;
    char d_getc();

    if (dsp->d_oprst == S_OPN) {
	if (d_fetch(dsp, A_DATA, dsp->d_size, dsp->d_dot, &val1) == ERR)
	  return ERR;
	if (d_fetch(dsp, A_DATA, dsp->d_size, d_getval(dsp), &val2) == ERR)
	  return ERR;
    }
    else {
	if (d_fetch(dsp, A_DATA, dsp->d_size, d_getval(dsp), &val1) == ERR)
	  return ERR;
	val2 = 0;
    }
    tst = d_getc(dsp);
    d_prc(dsp, tst);
    switch (tst) {
    case '=':
	if (val1 == val2) condition_flag = 1;
	else condition_flag = 0;
	break;
    case '<':
	if (val1 < val2) condition_flag = 1;
	else condition_flag = 0;
	break;
    case '>':
	if (val1 > val2) condition_flag = 1;
	else condition_flag = 0;
	break;
    default:
	return ERR;
    }
    if (!scriptp) {
	if (condition_flag) dsp->d_puts(" TRUE ");
	else dsp->d_puts(" FALSE ");
    }
    return OK;
}

/* If condition_flag is false, then reads from input stream until it
 * sees the matching $) (or until it sees a '\0').  Keeps count of $(
 * and $) so nesting works.
 */
intern retcd d_do_if(dsp)
reg ddtst *dsp;
{
    intf nested_level;
    char c;
    char d_getc();

    nested_level = 1;
    
    if (condition_flag == 0) {
	while (nested_level > 0) {
	    while ((c = d_getc(dsp)) != '')
	      if (c == '\0')
		return ERR;
	    c = d_getc(dsp);
	    if (c == '(') nested_level++;
	    else if (c == ')') nested_level--;
	}
	dsp->d_puts("$)");
    }
    return OK;
}

#endif DDTSCRIPT
