From: tbrannon@mars.csee.lehigh.edu (tbrannon)
Newsgroups: comp.lang.tcl
Subject: Problem with Tcl_Eval()
Date: 31 Aug 92 01:39:17 GMT
Organization: AI-LAB, Electrical Engineering and Computer Science, Lehigh
	University


I dont understand why math_string is taken literally and not evaluated
to the value that it is set to in the following sequence:

#define UGLY_STRING_1 "expect { timeout {send_user \"timeOUT occurred\"} -i "
#define UGLY_STRING_2 " -re \"$math_string(.*)\r\" {return $expect_out(1,string)}}"

static int
send_to_bc (clientData , interp , argc , argv)
     ClientData clientData ; Tcl_Interp * interp ; int argc ; char ** argv ;
{
  
  char 
    send_string [900] , * expect_string , *my_argv[5] , tmp_s [900] , 
    * math_string ;


  math_string = Tcl_Concat ( argc-1 , & argv [1] ) ;
  sprintf 
    (send_string , "send -i %d %s\\r" , (int) clientData , math_string ) ;

  my_argv[0] = UGLY_STRING_1 ;
  sprintf ( tmp_s , "%d" , (int) clientData ) ;
  my_argv[1] = tmp_s ;
  my_argv[2] = UGLY_STRING_2 ;

  expect_string = Tcl_Concat (3 , my_argv) ;

  Tcl_Eval
    (interp , send_string   , 0 , NULL) ;

  sprintf
    (tmp_s , "set math_string %s\r" , math_string) ;

/* this should set math_string in this tcl interpreter */
  Tcl_Eval 
    (interp , tmp_s , 0 , NULL) ;
/* this should expand out the value of math_string in the same
interpreter */
  Tcl_Eval
    (interp , expect_string , 0 , NULL) ;



  return TCL_OK ;

}


static int
cmd_bc_init (clientData , interp , argc , argv)
     ClientData clientData ; Tcl_Interp * interp ; int argc ; char ** argv ;
{

  char 
    * string ;
 
  if (argc != 2) {
    Tcl_AppendResult (interp , "wrong number of arguments: should be \"" ,
		     argv[0] , " calc_object_name\"" , NULL) ;
    return TCL_ERROR ;
  }

  Tcl_Eval
    (interp , "spawn bc \n" , 0 , NULL) ;
     
  string = Tcl_GetVar 
    (interp , "spawn_id" , NULL) ;

  Tcl_CreateCommand
    (interp , argv[1] , send_to_bc , (ClientData) atoi (string) , NULL) ;

  Tcl_Eval
    (interp , "expect *" , 0 , NULL) ;

  Tcl_SetResult
    (interp , string , TCL_VOLATILE) ;

  return TCL_OK ;

}


void
internal_bc_init ()
{

  Tcl_CreateCommand 
    (interp , "bc_init" , cmd_bc_init , (ClientData) 0 , NULL) ;

}



void
main(argc, argv)
int argc;
char *argv[];
{
	extern int optind;
	extern char *optarg;
	char *args;		/* ptr to string-rep of all args */

	int interactive = FALSE;
	int cmdlinecmds = FALSE;
	char *cmdfilename = 0;
	int newcmd;
	Tcl_CmdBuf buffer;

	int c;
	int rc;



	int sys_rc = TRUE;	/* read system rc file */
	int my_rc = TRUE;	/* read personal rc file */

	int tcl_major = atoi(TCL_VERSION);
	int tcl_minor;
	char *dot = strchr(TCL_VERSION,'.');

	static char oBuf[BUFSIZ]; /* MDW: Tue Jun 23 12:03:21 1992 */
	setbuf(stdout, oBuf); /* Must be before stdout is written or read */

	tcl_minor = atoi(dot+1);



	if (tcl_major < NEED_TCL_MAJOR || tcl_minor < NEED_TCL_MINOR) {
	       fprintf(stderr,
		       "Expect compiled with Tcl %d.%d but needs at least Tcl %d.%d\n",
		       tcl_major,tcl_minor,NEED_TCL_MAJOR,NEED_TCL_MINOR);
	       exit(-1);
	}

	argv0 = argv[0];

	init_cmd_interpreter();	/* Tcl interpreter */
	exp_init_pty();
	init_tty(); /* do this only now that pty's looked at orig tty state */

	/* initialize commands */
	internal_bc_init () ; /* added by Terry Brannon */
	init_expect();
	init_interact();
	init_spawn();
	init_trap();
	init_unit_random();

	Tcl_SetVar(interp,SCRIPTDIR_VARNAME,SCRIPTDIR,0);
	Tcl_SetVar(interp,VERSION_VARNAME,VERSION,0);

	while ((c = getopt(argc, argv, "c:df:inN")) != EOF) {
		switch(c) {
		case 'c': /* command */
			cmdlinecmds = TRUE;
			rc = Tcl_Eval(interp,optarg,0,(char **)0);

			if (rc != TCL_OK) {
			    errorlog("error in command: %s\r\n",
				cook(optarg,(int *)0));
		    	    if (rc != TCL_ERROR)
				errorlog("Tcl_Eval = %d\r\n",rc);
			    if (*interp->result != 0) {
				errorlog("%s\r\n",
					cook(interp->result,(int *)0));
			    }
			}
			break;
		case 'd': is_debugging = TRUE;
			debuglog("expect version %s\r\n",VERSION);
			break;
		case 'f': /* name of cmd file */
			cmdfilename = optarg;
			break;
		case 'i': /* interactive */
			interactive = TRUE;
			break;
		case 'n': /* don't read personal rc file */
			my_rc = FALSE;
			break;
		case 'N': /* don't read system-wide rc file */
			sys_rc = FALSE;
			break;
		default: usage();
		}
	}

	for (c = 0;c<argc;c++) {
		debuglog("argv[%d] = %s  ",c,argv[c]);
	}
	debuglog("\r\n");

	/* get cmd file name, if we haven't got it already */
	if (!cmdfilename && (optind < argc)) {
		cmdfilename = argv[optind];
		optind++;
	}
	if (cmdfilename) {
		if (streq(cmdfilename,"-")) {
			cmdfile = stdin;
		} else if (NULL == (cmdfile = fopen(cmdfilename,"r"))) {
			errorlog("%s: %s\r\n",cmdfilename,sys_errlist[errno]);
			bye(-1);
		}
	}

	if (cmdfile && interactive) {
		errorlog("cannot read commands from both file and keyboard\r\n");
		bye(-1);
	}

	/* collect remaining args and make into an argv */
	/* Tcl expects argv[0] to be the command name, but it doesn't do */
	/* anything useful with it anyway, so just back up the pointer */
	/* actually, back it up twice, so we can make the resultant [0] */
	/* be the program name */
	/* Oh, and we add to argc for the same reason */
	/* If no cmdfilename, there certainly can't be any args! */
	if (cmdfilename) {
		argv[optind-1] = cmdfilename;
		Tcl_ListCmd((ClientData)0,interp,2+argc-optind,argv+optind-2);
		args = interp->result;
	} else args = "";

	debuglog("set argv {%s}\r\n",args);
	Tcl_SetVar(interp,"argv",args,0);

	/* read rc files */
	if (sys_rc) {
	    char file[200];
	    int fd;

	    sprintf(file,"%sexpect.rc",SCRIPTDIR);
	    if (-1 != (fd = open(file,0))) {
		if (TCL_ERROR == (rc = Tcl_EvalFile(interp,file))) {
		    errorlog("error executing system initialization file: %s\r\n",file);
		    if (rc != TCL_ERROR) errorlog("Tcl_Eval = %d\r\n",rc);
		    if (*interp->result != 0) errorlog("%s\r\n",interp->result);
		    bye(-1);
		}
		close(fd);
	    }
	}
	if (my_rc) {
	    char file[200];
	    char *home;
	    int fd;
	    char *getenv();

	    if (NULL != (home = getenv("HOME"))) {
		sprintf(file,"%s/.expect.rc",home);
		if (-1 != (fd = open(file,0))) {
		    if (TCL_ERROR == (rc = Tcl_EvalFile(interp,file))) {
			errorlog("error executing file: %s\r\n",file);
			if (rc != TCL_ERROR) errorlog("Tcl_Eval = %d\r\n",rc);
			if (*interp->result != 0) errorlog("%s\r\n",interp->result);
			bye(-1);
		    }
		    close(fd);
	        }
	    }
	}


	/* become interactive if user requested or "nothing to do" */
	if (interactive || (!cmdfile && !cmdlinecmds)) 
	  (void) escape(interp); 

	if (!cmdfile) bye(0);

	debuglog("executing commands from command file\r\n");

	if (!(buffer = Tcl_CreateCmdBuf())) {
		errorlog("no more space for cmd buffer\r\n");
		bye(0);
	}
	newcmd = TRUE;
	while (1) {
		char line[BUFSIZ];/* buffer for partial Tcl command */
		char *ccmd;	/* pointer to complete Tcl command */

		if (fgets(line,BUFSIZ,cmdfile) == NULL) {
			if (newcmd) bye(0);
			else line[0] = 0;
		}
		if (NULL == (ccmd = Tcl_AssembleCmd(buffer,line))) {
			newcmd = FALSE;
			continue;	/* continue collecting command */
		}
		newcmd = TRUE;


		rc = Tcl_Eval(interp,ccmd,0,(char **)0);

		if (rc != TCL_OK) {
		    /* no \n at end, since ccmd will already have one. */
		    /* Actually, this is not true if command is last in */
		    /* file and has no newline after it, oh well */
		    errorlog("error in command: %s",cook(ccmd,(int *)0));
		    if (rc != TCL_ERROR) errorlog("Tcl_Eval = %d\r\n",rc);
		    if (*interp->result != 0) {
			errorlog("%s\r\n",cook(interp->result,(int *)0));
		    }
		}
	}
	/*NOTREACHED*/
}

#include "command.h"

/*ARGSUSED*/
int
cmdExpectVersion(clientData, interp, argc, argv)
ClientData clientData;
Tcl_Interp *interp;
int argc;
char **argv;
{
	int emajor, umajor;
	char *user_version;	/* user-supplied version string */

	if (argc == 1) {
		Tcl_SetResult(interp,exp_version,TCL_STATIC);
		return(TCL_OK);
	}
	if (argc > 3) {
		tcl_error("usage: expect_version [[-exit] version]");
		return(TCL_ERROR);
	}

	user_version = argv[argc==2?1:2];
	emajor = atoi(exp_version);
	umajor = atoi(user_version);

	/* first check major numbers */
	if (emajor > umajor) return(TCL_OK);
	else if (emajor == umajor) {
		int u, e;

		/* now check minor numbers */
		char *dot = strchr(user_version,'.');
		/* if user did not supply minor number, let it go */
		if (dot) {
			u = atoi(dot+1);
			dot = strchr(exp_version,'.');
			e = atoi(dot+1);
			if (e >= u) return(TCL_OK);
		}
	}

	if (argc == 2) {
		tcl_error("requires Expect version %s (but using %s)",
			argv0,user_version,exp_version);
		return(TCL_ERROR);
	}
	errorlog("%s: requires Expect version %s (but using %s)\r\n",
		argv0,user_version,exp_version);
	bye(-1);
	/*NOTREACHED*/
}
--
Terry Brannon
tb06@pl122a.eecs.lehigh.edu
Newsgroups: comp.lang.tcl