1 /* exp_main_sub.c - miscellaneous subroutines for Expect or Tk main() */
15 #ifdef HAVE_SYS_WAIT_H
21 #include "exp_rename.h"
23 #include "exp_command.h"
24 #include "exp_tty_in.h"
26 #include "exp_event.h"
32 #define EXP_VERSION PACKAGE_VERSION
36 #define EXP_VERSION "5.45.4" /* I give up! */
37 /* It is not necessary that number */
38 /* be accurate. It is just here to */
39 /* pacify Centerline which doesn't */
40 /* seem to be able to get it from */
43 #define SCRIPTDIR "example/"
45 #define EXECSCRIPTDIR "example/"
47 char exp_version[] = PACKAGE_VERSION;
48 #define NEED_TCL_MAJOR 7
49 #define NEED_TCL_MINOR 5
51 char *exp_argv0 = "this program"; /* default program name */
52 void (*exp_app_exit)() = 0;
53 void (*exp_event_exit)() = 0;
54 FILE *exp_cmdfile = 0;
55 char *exp_cmdfilename = 0;
56 int exp_cmdlinecmds = FALSE;
57 int exp_interactive = FALSE;
58 int exp_buffer_command_input = FALSE;/* read in entire cmdfile at once */
61 Tcl_Interp *exp_interp; /* for use by signal handlers who can't figure out */
62 /* the interpreter directly */
63 int exp_tcl_debugger_available = FALSE;
67 int exp_strict_write = 0;
74 char buffer [] = "exit 1";
75 expErrorLog("usage: expect [-div] [-c cmds] [[-f] cmdfile] [args]\r\n");
77 /* SF #439042 -- Allow overide of "exit" by user / script
79 Tcl_Eval(interp, buffer);
82 /* this clumsiness because pty routines don't know Tcl definitions */
86 exp_pty_exit_for_tcl(clientData)
87 ClientData clientData;
96 Tcl_CreateExitHandler(exp_pty_exit_for_tcl,(ClientData)0);
99 /* This can be called twice or even recursively - it's safe. */
101 exp_exit_handlers(clientData)
102 ClientData clientData;
104 extern int exp_forked;
106 Tcl_Interp *interp = (Tcl_Interp *)clientData;
108 /* use following checks to prevent recursion in exit handlers */
109 /* if this code ever supports multiple interps, these should */
110 /* become interp-specific */
112 static int did_app_exit = FALSE;
113 static int did_expect_exit = FALSE;
115 if (!did_expect_exit) {
116 did_expect_exit = TRUE;
117 /* called user-defined exit routine if one exists */
118 if (exp_onexit_action) {
119 int result = Tcl_GlobalEval(interp,exp_onexit_action);
120 if (result != TCL_OK) Tcl_BackgroundError(interp);
123 expDiagLogU("onexit handler called recursively - forcing exit\r\n");
129 (*exp_app_exit)(interp);
131 expDiagLogU("application exit handler called recursively - forcing exit\r\n");
135 if (!exp_disconnected
137 && (exp_dev_tty != -1)
138 && isatty(exp_dev_tty)) {
139 if (exp_ioctled_devtty) {
140 exp_tty_set(interp,&exp_tty_original,exp_dev_tty,0);
143 /* all other files either don't need to be flushed or will be
144 implicitly closed at exit. Spawned processes are free to continue
145 running, however most will shutdown after seeing EOF on stdin.
146 Some systems also deliver SIGHUP and other sigs to idle processes
147 which will blow them away if not prepared.
150 exp_close_all(interp);
154 history_nextid(interp)
157 /* unncessarily tricky coding - if nextid isn't defined,
158 maintain our own static version */
160 static int nextid = 0;
161 CONST char *nextidstr = Tcl_GetVar2(interp,"tcl::history","nextid",0);
163 /* intentionally ignore failure */
164 (void) sscanf(nextidstr,"%d",&nextid);
169 /* this stupidity because Tcl needs commands in writable space */
170 static char prompt1[] = "prompt1";
171 static char prompt2[] = "prompt2";
173 static char *prompt2_default = "+> ";
174 static char prompt1_default[] = "expect%d.%d> ";
178 Exp_Prompt1ObjCmd(clientData, interp, objc, objv)
179 ClientData clientData;
182 Tcl_Obj *CONST objv[]; /* Argument objects. */
184 static char buffer[200];
186 Interp *iPtr = (Interp *)interp;
188 sprintf(buffer,prompt1_default,iPtr->numLevels,history_nextid(interp));
189 Tcl_SetResult(interp,buffer,TCL_STATIC);
195 Exp_Prompt2ObjCmd(clientData, interp, objc, objv)
196 ClientData clientData;
199 Tcl_Obj *CONST objv[];
201 Tcl_SetResult(interp,prompt2_default,TCL_STATIC);
207 ignore_procs(interp,s)
209 char *s; /* function name */
211 return ((s[0] == 'p') &&
223 /* handle an error from Tcl_Eval or Tcl_EvalFile */
225 handle_eval_error(interp,check_for_nostack)
227 int check_for_nostack;
231 /* if errorInfo has something, print it */
232 /* else use what's in the interp result */
234 msg = Tcl_GetVar(interp,"errorInfo",TCL_GLOBAL_ONLY);
235 if (!msg) msg = Tcl_GetStringResult (interp);
236 else if (check_for_nostack) {
237 /* suppress errorInfo if generated via */
238 /* error ... -nostack */
239 if (0 == strncmp("-nostack",msg,8)) return;
242 * This shouldn't be necessary, but previous test fails
243 * because of recent change John made - see eval_trap_action()
244 * in exp_trap.c for more info
246 if (exp_nostack_dump) {
247 exp_nostack_dump = FALSE;
252 /* no \n at end, since ccmd will already have one. */
253 /* Actually, this is not true if command is last in */
254 /* file and has no newline after it, oh well */
255 expErrorLogU(exp_cook(msg,(int *)0));
256 expErrorLogU("\r\n");
259 /* user has pressed escape char from interact or somehow requested expect.
260 If a user-supplied command returns:
262 TCL_ERROR, assume user is experimenting and reprompt
264 TCL_RETURN, return TCL_OK (assume user just wants to escape() to return)
265 EXP_TCL_RETURN, return TCL_RETURN
266 anything else return it
269 exp_interpreter(interp,eofObj)
273 Tcl_Obj *commandPtr = NULL;
276 Interp *iPtr = (Interp *)interp;
277 int tty_changed = FALSE;
279 int was_raw, was_echo;
281 Tcl_Channel inChannel, outChannel;
282 ExpState *esPtr = expStdinoutGet();
283 /* int fd = fileno(stdin);*/
286 commandPtr = Tcl_NewObj();
287 Tcl_IncrRefCount(commandPtr);
291 if (Tcl_IsShared(commandPtr)) {
292 Tcl_DecrRefCount(commandPtr);
293 commandPtr = Tcl_DuplicateObj(commandPtr);
294 Tcl_IncrRefCount(commandPtr);
296 outChannel = expStdinoutGet()->channel;
298 Tcl_Flush(outChannel);
305 /* force terminal state */
306 tty_changed = exp_tty_cooked_echo(interp,&tty_old,&was_raw,&was_echo);
309 code = Tcl_Eval(interp,prompt1);
310 if (code == TCL_OK) {
311 expStdoutLogU(Tcl_GetStringResult(interp),1);
313 else expStdoutLog(1,prompt1_default,iPtr->numLevels,history_nextid(interp));
315 code = Tcl_Eval(interp,prompt2);
316 if (code == TCL_OK) {
317 expStdoutLogU(Tcl_GetStringResult(interp),1);
319 else expStdoutLogU(prompt2_default,1);
322 esPtr->force_read = 1;
323 code = exp_get_next_event(interp,&esPtr,1,&esPtr,EXP_TIME_INFINITY,
325 /* check for code == EXP_TCLERROR? */
327 if (code != EXP_EOF) {
328 inChannel = expStdinoutGet()->channel;
329 code = Tcl_GetsObj(inChannel, commandPtr);
331 if (code == -1 && errno == EINTR) {
332 if (Tcl_AsyncReady()) {
333 (void) Tcl_AsyncInvoke(interp,TCL_OK);
338 if (code < 0) code = EXP_EOF;
339 if ((code == 0) && Tcl_Eof(inChannel) && !gotPartial) code = EXP_EOF;
343 if (code == EXP_EOF) {
345 code = Tcl_EvalObjEx(interp,eofObj,0);
352 expDiagWriteObj(commandPtr);
353 /* intentionally always write to logfile */
354 if (expLogChannelGet()) {
355 Tcl_WriteObj(expLogChannelGet(),commandPtr);
357 /* no need to write to stdout, since they will see */
358 /* it just from it having been echoed as they are */
362 * Add the newline removed by Tcl_GetsObj back to the string.
365 if (Tcl_IsShared(commandPtr)) {
366 Tcl_DecrRefCount(commandPtr);
367 commandPtr = Tcl_DuplicateObj(commandPtr);
368 Tcl_IncrRefCount(commandPtr);
370 Tcl_AppendToObj(commandPtr, "\n", 1);
371 if (!TclObjCommandComplete(commandPtr)) {
376 Tcl_AppendToObj(commandPtr, "\n", 1);
377 if (!TclObjCommandComplete(commandPtr)) {
384 if (tty_changed) exp_tty_set(interp,&tty_old,was_raw,was_echo);
386 code = Tcl_RecordAndEvalObj(interp, commandPtr, 0);
387 Tcl_DecrRefCount(commandPtr);
388 commandPtr = Tcl_NewObj();
389 Tcl_IncrRefCount(commandPtr);
394 str = Tcl_GetStringResult(interp);
396 expStdoutLogU(exp_cook(str,(int *)0),1);
397 expStdoutLogU("\r\n",1);
401 handle_eval_error(interp,1);
402 /* since user is typing by hand, we expect lots */
403 /* of errors, and want to give another chance */
405 #define finish(x) {code = x; goto done;}
414 /* note that ccmd has trailing newline */
415 expErrorLog("error %d: ",code);
416 expErrorLogU(Tcl_GetString(Tcl_GetObjResult(interp)));
417 expErrorLogU("\r\n");
421 /* cannot fall thru here, must jump to label */
423 if (tty_changed) exp_tty_set(interp,&tty_old,was_raw,was_echo);
425 Tcl_DecrRefCount(commandPtr);
431 Exp_ExpVersionObjCmd(clientData, interp, objc, objv)
432 ClientData clientData;
435 Tcl_Obj *CONST objv[]; /* Argument objects. */
438 char *user_version; /* user-supplied version string */
441 Tcl_SetResult(interp,exp_version,TCL_STATIC);
445 exp_error(interp,"usage: expect_version [[-exit] version]");
449 user_version = Tcl_GetString (objv[objc==2?1:2]);
450 emajor = atoi(exp_version);
451 umajor = atoi(user_version);
453 /* first check major numbers */
454 if (emajor == umajor) {
457 /* now check minor numbers */
458 char *dot = strchr(user_version,'.');
460 exp_error(interp,"version number must include a minor version number");
465 dot = strchr(exp_version,'.');
467 if (e >= u) return(TCL_OK);
471 exp_error(interp,"%s requires Expect version %s (but using %s)",
472 exp_argv0,user_version,exp_version);
475 expErrorLog("%s requires Expect version %s (but is using %s)\r\n",
476 exp_argv0,user_version,exp_version);
478 /* SF #439042 -- Allow overide of "exit" by user / script
481 char buffer [] = "exit 1";
482 Tcl_Eval(interp, buffer);
484 /*NOTREACHED, but keep compiler from complaining*/
488 static char init_auto_path[] = "\
489 if {$exp_library != \"\"} {\n\
490 lappend auto_path $exp_library\n\
492 if {$exp_exec_library != \"\"} {\n\
493 lappend auto_path $exp_exec_library\n\
497 DeleteCmdInfo (clientData, interp)
498 ClientData clientData;
509 static int first_time = TRUE;
511 Tcl_CmdInfo* close_info = NULL;
512 Tcl_CmdInfo* return_info = NULL;
515 #ifndef USE_TCL_STUBS
516 int tcl_major = atoi(TCL_VERSION);
517 char *dot = strchr(TCL_VERSION,'.');
518 int tcl_minor = atoi(dot+1);
520 if (tcl_major < NEED_TCL_MAJOR ||
521 (tcl_major == NEED_TCL_MAJOR && tcl_minor < NEED_TCL_MINOR)) {
525 Tcl_Obj* s = Tcl_NewStringObj (exp_argv0,-1);
527 sprintf(bufa,"%d.%d",tcl_major,tcl_minor);
528 sprintf(bufb,"%d.%d",NEED_TCL_MAJOR,NEED_TCL_MINOR);
530 Tcl_AppendStringsToObj (s,
531 " compiled with Tcl ", bufa,
532 " but needs at least Tcl ", bufb,
534 Tcl_SetObjResult (interp, s);
540 #ifndef USE_TCL_STUBS
541 if (Tcl_PkgRequire(interp, "Tcl", TCL_VERSION, 0) == NULL) {
545 if (Tcl_InitStubs(interp, "8.1", 0) == NULL) {
551 * Save initial close and return for later use
554 close_info = (Tcl_CmdInfo*) ckalloc (sizeof (Tcl_CmdInfo));
555 if (Tcl_GetCommandInfo(interp, "close", close_info) == 0) {
556 ckfree ((char*) close_info);
559 return_info = (Tcl_CmdInfo*) ckalloc (sizeof (Tcl_CmdInfo));
560 if (Tcl_GetCommandInfo(interp, "return", return_info) == 0){
561 ckfree ((char*) close_info);
562 ckfree ((char*) return_info);
565 Tcl_SetAssocData (interp, EXP_CMDINFO_CLOSE, DeleteCmdInfo, (ClientData) close_info);
566 Tcl_SetAssocData (interp, EXP_CMDINFO_RETURN, DeleteCmdInfo, (ClientData) return_info);
569 * Expect redefines close so we need to save the original (pre-expect)
570 * definition so it can be restored before exiting.
572 * Needed when expect is dynamically loaded after close has
573 * been redefined e.g. the virtual file system in tclkit
575 if (TclRenameCommand(interp, "close", "_close.pre_expect") != TCL_OK) {
579 if (Tcl_PkgProvide(interp, "Expect", PACKAGE_VERSION) != TCL_OK) {
583 Tcl_Preserve(interp);
584 Tcl_CreateExitHandler(Tcl_Release,(ClientData)interp);
587 exp_getpid = getpid();
590 exp_init_tty(); /* do this only now that we have looked at */
591 /* original tty state */
596 exp_init_unit_random();
597 exp_init_spawn_ids(interp);
601 expDiagLogPtrSet(expDiagLogU);
602 expErrnoMsgSet(Tcl_ErrnoMsg);
604 Tcl_CreateExitHandler(exp_exit_handlers,(ClientData)interp);
609 /* save last known interp for emergencies */
612 /* initialize commands */
613 exp_init_most_cmds(interp); /* add misc cmds to interpreter */
614 exp_init_expect_cmds(interp); /* add expect cmds to interpreter */
615 exp_init_main_cmds(interp); /* add main cmds to interpreter */
616 exp_init_trap_cmds(interp); /* add trap cmds to interpreter */
617 exp_init_tty_cmds(interp); /* add tty cmds to interpreter */
618 exp_init_interact_cmds(interp); /* add interact cmds to interpreter */
620 /* initialize variables */
621 exp_init_spawn_id_vars(interp);
625 * For each of the the Tcl variables, "expect_library",
626 *"exp_library", and "exp_exec_library", set the variable
627 * if it does not already exist. This mechanism allows the
628 * application calling "Expect_Init()" to set these varaibles
629 * to alternate locations from where Expect was built.
632 if (Tcl_GetVar(interp, "expect_library", TCL_GLOBAL_ONLY) == NULL) {
633 Tcl_SetVar(interp,"expect_library",SCRIPTDIR,0);/* deprecated */
635 if (Tcl_GetVar(interp, "exp_library", TCL_GLOBAL_ONLY) == NULL) {
636 Tcl_SetVar(interp,"exp_library",SCRIPTDIR,0);
638 if (Tcl_GetVar(interp, "exp_exec_library", TCL_GLOBAL_ONLY) == NULL) {
639 Tcl_SetVar(interp,"exp_exec_library",EXECSCRIPTDIR,0);
642 Tcl_Eval(interp,init_auto_path);
643 Tcl_ResetResult(interp);
646 Dbg_IgnoreFuncs(interp,ignore_procs);
652 static char sigint_init_default[80];
653 static char sigterm_init_default[80];
654 static char debug_init_default[] = "trap {exp_debug 1} SIGINT";
657 exp_parse_argv(interp,argc,argv)
662 char argc_rep[10]; /* enough space for storing literal rep of argc */
664 int sys_rc = TRUE; /* read system rc file */
665 int my_rc = TRUE; /* read personal rc file */
672 char *args; /* ptr to string-rep of all args */
678 Dbg_ArgcArgv(argc,argv,1);
681 /* initially, we must assume we are not interactive */
682 /* this prevents interactive weirdness courtesy of unknown via -c */
683 /* after handling args, we can change our mind */
684 Tcl_SetVar(interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY);
686 /* there's surely a system macro to do this but I don't know what it is */
687 #define EXP_SIG_EXIT(signalnumber) (0x80|signalnumber)
689 sprintf(sigint_init_default, "trap {exit %d} SIGINT", EXP_SIG_EXIT(SIGINT));
690 Tcl_Eval(interp,sigint_init_default);
691 sprintf(sigterm_init_default,"trap {exit %d} SIGTERM",EXP_SIG_EXIT(SIGTERM));
692 Tcl_Eval(interp,sigterm_init_default);
695 * [#418892]. The '+' character in front of every other option
696 * declaration causes 'GNU getopt' to deactivate its
697 * non-standard behaviour and switch to POSIX. Other
698 * implementations of 'getopt' might recognize the option '-+'
699 * because of this, but the following switch will catch this
700 * and generate a usage message.
703 while ((c = getopt(argc, argv, "+b:c:dD:f:inN-v")) != EOF) {
706 /* getopt already handles -- internally, however */
707 /* this allows us to abort getopt when dash is at */
708 /* the end of another option which is required */
709 /* in order to allow things like -n- on #! line */
711 case 'c': /* command */
712 exp_cmdlinecmds = TRUE;
713 rc = Tcl_Eval(interp,optarg);
715 expErrorLogU(exp_cook(Tcl_GetVar(interp,"errorInfo",TCL_GLOBAL_ONLY),(int *)0));
716 expErrorLogU("\r\n");
719 case 'd': expDiagToStderrSet(TRUE);
720 expDiagLog("expect version %s\r\n",exp_version);
724 exp_tcl_debugger_available = TRUE;
725 if (Tcl_GetInt(interp,optarg,&rc) != TCL_OK) {
726 expErrorLog("%s: -D argument must be 0 or 1\r\n",exp_argv0);
728 /* SF #439042 -- Allow overide of "exit" by user / script
731 char buffer [] = "exit 1";
732 Tcl_Eval(interp, buffer);
736 /* set up trap handler before Dbg_On so user does */
737 /* not have to see it at first debugger prompt */
738 if (0 == (debug_init = getenv("EXPECT_DEBUG_INIT"))) {
739 debug_init = debug_init_default;
741 Tcl_Eval(interp,debug_init);
742 if (rc == 1) Dbg_On(interp,0);
745 case 'f': /* name of cmd file */
746 exp_cmdfilename = optarg;
748 case 'b': /* read cmdfile one part at a time */
749 exp_cmdfilename = optarg;
750 exp_buffer_command_input = TRUE;
752 case 'i': /* interactive */
753 exp_interactive = TRUE;
755 case 'n': /* don't read personal rc file */
758 case 'N': /* don't read system-wide rc file */
762 printf("expect version %s\n", exp_version);
764 /* SF #439042 -- Allow overide of "exit" by user / script
767 char buffer [] = "exit 0";
768 Tcl_Eval(interp, buffer);
771 default: usage(interp);
777 for (c = 0;c<argc;c++) {
778 expDiagLog("argv[%d] = ",c);
779 expDiagLogU(argv[c]);
784 /* if user hasn't explicitly requested we be interactive */
785 /* look for a file or some other source of commands */
786 if (!exp_interactive) {
787 /* get cmd file name, if we haven't got it already */
788 if (!exp_cmdfilename && (optind < argc)) {
789 exp_cmdfilename = argv[optind];
793 * [#418892]. Skip a "--" found immediately
794 * behind the name of the script to
795 * execute. Don't try this if there are no
796 * arguments behind the "--" anymore. All
797 * other appearances of "--" are handled by
798 * the "getopt"-loop above.
801 if ((optind < argc) &&
802 (0 == strcmp ("--", argv[optind]))) {
807 if (exp_cmdfilename) {
808 if (streq(exp_cmdfilename,"-")) {
811 } else if (exp_buffer_command_input) {
813 exp_cmdfile = fopen(exp_cmdfilename,"r");
816 expCloseOnExec(fileno(exp_cmdfile));
821 msg = "could not read - odd file name?";
823 msg = Tcl_ErrnoMsg(errno);
825 expErrorLog("%s: %s\r\n",exp_cmdfilename,msg);
827 /* SF #439042 -- Allow overide of "exit" by user / script
830 char buffer [] = "exit 1";
831 Tcl_Eval(interp, buffer);
835 } else if (!exp_cmdlinecmds) {
837 /* no other source of commands, force interactive */
838 exp_interactive = TRUE;
840 /* read cmds from redirected stdin */
846 if (exp_interactive) {
847 Tcl_SetVar(interp, "tcl_interactive","1",TCL_GLOBAL_ONLY);
850 /* collect remaining args and make into argc, argv0, and argv */
851 sprintf(argc_rep,"%d",argc-optind);
852 Tcl_SetVar(interp,"argc",argc_rep,0);
853 expDiagLog("set argc %s\r\n",argc_rep);
855 if (exp_cmdfilename) {
856 Tcl_SetVar(interp,"argv0",exp_cmdfilename,0);
857 expDiagLog("set argv0 \"%s\"\r\n",exp_cmdfilename);
859 Tcl_SetVar(interp,"argv0",exp_argv0,0);
860 expDiagLog("set argv0 \"%s\"\r\n",exp_argv0);
863 args = Tcl_Merge(argc-optind,argv+optind);
864 expDiagLogU("set argv \"");
866 expDiagLogU("\"\r\n");
867 Tcl_SetVar(interp,"argv",args,0);
870 exp_interpret_rcfiles(interp,my_rc,sys_rc);
874 print_result (interp)
877 char* msg = Tcl_GetStringResult (interp);
880 expErrorLogU("\r\n");
888 /* SF #439042 -- Allow overide of "exit" by user / script
890 char buffer [] = "exit 1";
891 Tcl_Eval(interp, buffer);
896 exp_interpret_rcfiles(interp,my_rc,sys_rc)
907 sprintf(file,"%s/expect.rc",SCRIPTDIR);
908 if (-1 != (fd = open(file,0))) {
909 if (TCL_ERROR == (rc = Tcl_EvalFile(interp,file))) {
910 expErrorLog("error executing system initialization file: %s\r\n",file);
912 expErrorLog("Tcl_Eval = %d\r\n",rc);
913 print_result (interp);
925 if ((NULL != (home = getenv("DOTDIR"))) ||
926 (NULL != (home = getenv("HOME")))) {
927 sprintf(file,"%s/.expect.rc",home);
928 if (-1 != (fd = open(file,0))) {
929 if (TCL_ERROR == (rc = Tcl_EvalFile(interp,file))) {
930 expErrorLog("error executing file: %s\r\n",file);
932 expErrorLog("Tcl_Eval = %d\r\n",rc);
933 print_result (interp);
943 exp_interpret_cmdfilename(interp,filename)
949 expDiagLog("executing commands from command file %s\r\n",filename);
951 Tcl_ResetResult(interp);
952 if (TCL_OK != (rc = Tcl_EvalFile(interp,filename))) {
953 /* EvalFile doesn't bother to copy error to errorInfo */
955 Tcl_AddErrorInfo(interp, "");
956 handle_eval_error(interp,0);
962 exp_interpret_cmdfile(interp,fp)
971 Tcl_DStringInit(&dstring);
973 expDiagLogU("executing commands from command file\r\n");
978 char line[BUFSIZ];/* buffer for partial Tcl command */
979 char *ccmd; /* pointer to complete Tcl command */
981 if (fgets(line,BUFSIZ,fp) == NULL) {
982 if (!gotPartial) break;
985 ccmd = Tcl_DStringAppend(&dstring,line,-1);
986 if (!Tcl_CommandComplete(ccmd) && !eof) {
988 continue; /* continue collecting command */
992 rc = Tcl_Eval(interp,ccmd);
993 Tcl_DStringFree(&dstring);
995 handle_eval_error(interp,0);
1000 Tcl_DStringFree(&dstring);
1004 static struct exp_cmd_data cmd_data[] = {
1005 {"exp_version", Exp_ExpVersionObjCmd, 0, 0, 0},
1006 {"prompt1", Exp_Prompt1ObjCmd, 0, 0, EXP_NOPREFIX},
1007 {"prompt2", Exp_Prompt2ObjCmd, 0, 0, EXP_NOPREFIX},
1011 exp_init_main_cmds(interp)
1014 exp_create_commands(interp,cmd_data);