📄 expect.c
字号:
/* * Copyright (C) 1996-1998 by the Board of Trustees * of Leland Stanford Junior University. * * This file is part of the SimOS distribution. * See LICENSE file for terms of the license. * *//***************************************************************** * expect.c * * Expect scripting facility for SimOS * ****************************************************************/#include <stdio.h>#include <unistd.h>#include <sys/types.h>#include <string.h>#include <stdlib.h>#include <fcntl.h>#include <math.h>#include <setjmp.h>#include <ctype.h>#include <assert.h>#include "syslimits.h"#include "simutil.h"#include "sim_error.h"#include "machine_params.h"#include "memstat.h"#include "annotations.h"#include "cpu_interface.h"#include "symbols.h"#include "tcl_init.h"#include "hw_events.h"#include "visual.h"#include "checkpoint.h"#define MAX_OUT_STRING 8192 /* max. size of output string to compare */typedef struct ConInfo ConInfo;typedef struct Trigger Trigger;struct ConInfo { char out[MAX_OUT_STRING+1]; int outindx; char in[MAX_OUT_STRING]; int front; int back;};struct Trigger { Tcl_Interp *interp; int console; char *pattern; char *script; Trigger *next;};static ConInfo *ci;static Trigger *triggers;static int ExpectCmd(ClientData data, Tcl_Interp *interp, int argc, char *argv[]);static int TypeCmd(ClientData data, Tcl_Interp *interp, int argc, char *argv[]);void ExpectInit(Tcl_Interp *interp){ int i; ASSERT(SIM_MAXCPUS); ci = (ConInfo *) malloc(sizeof(ConInfo) * SIM_MAXCPUS); bzero((char*)ci,sizeof(ConInfo) * SIM_MAXCPUS); Tcl_CreateCommand(interp, "expect", ExpectCmd, (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL); Tcl_CreateCommand(interp, "type", TypeCmd, (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL); triggers = NULL; for (i=0; i<SIM_MAXCPUS; i++) { ci[i].outindx = 0; ci[i].out[0] = '\0'; ci[i].front = 0; ci[i].back = 0; ci[i].in[0] = '\0'; }}int ExpectCmd(ClientData data, Tcl_Interp *interp, int argc, char *argv[]){ char *pattern; int console; char *script; Trigger *newtrig; if (argc == 3) { console = -1; pattern = argv[1]; script = argv[2]; } else if (argc == 4) { pattern = argv[2]; script = argv[3]; if (Tcl_GetInt(interp, argv[1], &console) != TCL_OK) { Tcl_AppendResult(interp, "consolenum must an int", NULL); return TCL_ERROR; } if (console < 0 ) { Tcl_AppendResult(interp, "bad consolenum \"", argv[1], "\"", NULL); return TCL_ERROR; } } else { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " ?consolenum? pattern script\"", NULL); return TCL_ERROR; } newtrig = (Trigger*)MALLOC(sizeof(Trigger), "Trigger"); newtrig->interp = interp; newtrig->console = console; newtrig->pattern = SaveString(pattern); newtrig->script = SaveString(script); newtrig->next = triggers; triggers = newtrig; return TCL_OK;}extern bool sim_console_has_char(int);int TypeCmd(ClientData data, Tcl_Interp *interp, int argc, char *argv[]){ char *string; int console; if (argc == 2) { string = argv[1]; console = 0; } else if (argc == 3) { string = argv[2]; if (Tcl_GetInt(interp, argv[1], &console) != TCL_OK) { Tcl_AppendResult(interp, "consolenum must an int", NULL); return TCL_ERROR; } ASSERT(TOTAL_CONSOLES); if ((console < 0 ) || (console >= TOTAL_CONSOLES)) { Tcl_AppendResult(interp, "bad consolenum \"", argv[1], "\"", NULL); return TCL_ERROR; } } else { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " ?consolenum? string\"", NULL); return TCL_ERROR; }#ifndef SIM_X86 sim_console_has_char(console);#endif while (*string) { if (ci[console].back == (ci[console].front-1)) { Tcl_AppendResult(interp, "overflowed internal buffer", NULL); return TCL_ERROR; } ci[console].in[ci[console].back] = *string; ci[console].back = (ci[console].back + 1) % MAX_OUT_STRING; string++; }#ifdef SIM_X86 sim_console_has_char(console);#endif return TCL_OK;}char ExpectGetChar(int consoleNum){ if (ci[consoleNum].back == ci[consoleNum].front) { return '\0'; } return ci[consoleNum].in[ci[consoleNum].front++];}void ExpectPutChar(int consoleNum, char ch){ Trigger *trig = triggers; if (ci[consoleNum].outindx < MAX_OUT_STRING) { ci[consoleNum].out[ci[consoleNum].outindx++] = ch; ci[consoleNum].out[ci[consoleNum].outindx] = '\0'; while (trig) { if ((trig->console == -1) || (trig->console == consoleNum)) { if (Tcl_StringMatch(ci[consoleNum].out, trig->pattern)) { if (Tcl_GlobalEval(trig->interp, trig->script) != TCL_OK) { HandleError(trig->interp, trig->script); } } } trig = trig->next; } } if ((ch == '\n') || (ch == '\r')) { ci[consoleNum].out[0] = '\0'; ci[consoleNum].outindx = 0; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -