📄 script.c
字号:
} seq[f] = thisline; thisline = thisline->next; } if (f == 16) syntaxerr("(too many arguments)"); return(seq);}/* * Our "expect" function. */int expect(text)char *text;{ char *s, *w; struct line **seq; struct line oneline; struct line *dflseq[2]; char *toact = "exit 1"; int found = 0, f, val, c; char *already, *action = CNULL; if (inexpect) { s_error("script \"%s\" line %d: nested expect\r\n", curenv->scriptname, thisline->lineno); exit(1); } etimeout = 120; inexpect = 1; s = getword(&text); if (!strcmp(s, "{")) { if (*text) syntaxerr("(garbage after {)"); thisline = thisline->next; seq = buildexpect(); } else { dflseq[1] = LNULL; dflseq[0] = &oneline; oneline.line = text; oneline.next = LNULL; } /* Seek a timeout command */ for(f = 0; seq[f]; f++) { if (!strncmp(seq[f]->line, "timeout", 7)) { c = seq[f]->line[7]; if (c == 0 || (c != ' ' && c != '\t')) continue; s = seq[f]->line + 7; seq[f] = LNULL; skipspace(&s); w = getword(&s); if (w == CNULL) syntaxerr("(argument expected)"); val = getnum(w); if (val == 0) syntaxerr("(invalid argument)"); etimeout = val; skipspace(&s); if (*s != 0) toact = s; break; } } if (setjmp(ejmp) != 0) { f = s_exec(toact); inexpect = 0; return(f); } /* Allright. Now do the expect. */ c = OK; while(!found) { action = CNULL; already = readchar(); for(f = 0; seq[f]; f++) { s = seq[f]->line; w = getword(&s); if (expfound(already, w)) { action = s; found = 1; break; } } if (action != CNULL && *action) { found = 0; /* Maybe BREAK or RETURN */ if ((c = s_exec(action)) != OK) found = 1; } } inexpect = 0; etimeout = 0; return(c);}/* * Jump to a shell and run a command. */int shell(text)char *text;{ laststatus = system(text); return(OK);}/* * Send output to stdout ( = modem) */int dosend(text)char *text;{ newline = "\r"; return(output(text, stdout));}/* * Exit from the script, possibly with a value. */int doexit(text)char *text;{ char *w; int ret = 0; w = getword(&text); if (w != CNULL) ret = getnum(w); curenv->exstat = ret; longjmp(curenv->ebuf, 1); return(0);}/* * Goto a specific label. */int dogoto(text)char *text;{ char *w; struct line *l; char buf[32]; int len; w = getword(&text); if (w == CNULL || *text) syntaxerr("(in goto/gosub label)"); sprintf(buf, "%s:", w); len = strlen(buf); for(l = curenv->lines; l; l = l->next) if (!strncmp(l->line, buf, len)) break; if (l == LNULL) { s_error("script \"%s\" line %d: label \"%s\" not found\r\n", curenv->scriptname, thisline->lineno, w); exit(1); } thisline = l; /* We return break, to automatically break out of expect loops. */ return(BREAK);}/* * Goto a subroutine. */int dogosub(text)char *text;{ struct line *oldline; int ret = OK; oldline = thisline; dogoto(text); while(ret != ERR) { if ((thisline = thisline->next) == LNULL) { s_error("script \"%s\": no return from gosub\r\n", curenv->scriptname); exit(1); } ret = s_exec(thisline->line); if (ret == RETURN) { ret = OK; thisline = oldline; break; } } return(ret);}/* * Return from a subroutine. */int doreturn(text)char *text;{ return(RETURN);}/* * Print text to stderr. */int print(text)char *text;{ newline = "\r\n"; return(output(text, stderr));}/* * Declare a variable (integer) */int doset(text)char *text;{ char *w; struct var *v; w = getword(&text); if (w == CNULL) syntaxerr("(missing var name)"); v = getvar(w, 1); if (*text) v->value = getnum(getword(&text)); return(OK);} /* * Lower the value of a variable. */int dodec(text)char *text;{ char *w; struct var *v; w = getword(&text); if (w == CNULL) syntaxerr("(expected variable)"); v = getvar(w, 0); v->value--; return(OK);}/* * Increase the value of a variable. */int doinc(text)char *text;{ char *w; struct var *v; w = getword(&text); if (w == CNULL) syntaxerr("(expected variable)"); v = getvar(w, 0); v->value++; return(OK);}/* * If syntax: if n1 [><=] n2 command. */int doif(text)char *text;{ char *w; int n1; int n2; char op; if ((w = getword(&text)) == CNULL) syntaxerr("(if)"); n1 = getnum(w); if ((w = getword(&text)) == CNULL) syntaxerr("(if)"); if (*w == 0 || w[1] != 0) syntaxerr("(if)"); op = *w; if ((w = getword(&text)) == CNULL) syntaxerr("(if)"); n2 = getnum(w); if (!*text) syntaxerr("(expected command after if)"); if (op == '=') { if (n1 != n2) return(OK); } else if (op == '>') { if (n1 <= n2) return(OK); } else if (op == '<') { if (n1 >= n2) return(OK); } else { syntaxerr("(unknown operator)"); } return(s_exec(text));}/* * Set the global timeout-time. */int dotimeout(text)char *text;{ char *w; int val; w = getword(&text); if(w == CNULL) syntaxerr("(argument expected)"); if ((val = getnum(w)) == 0) syntaxerr("(invalid argument)"); gtimeout = val; return(OK);}/* * Turn verbose on/off (= echo stdin to stderr) */int doverbose(text)char *text;{ char *w; curenv->verbose = 1; if ((w = getword(&text)) != CNULL) { if (!strcmp(w, "on")) return(OK); if (!strcmp(w, "off")) { curenv->verbose = 0; return(OK); } } syntaxerr("(unexpected argument)"); return(ERR);}/* * Sleep for a certain number of seconds. */int dosleep(text)char *text;{ int foo, tm; tm = getnum(text); foo = gtimeout - tm; /* The alarm goes off every second.. */ while(gtimeout != foo) pause(); return(OK);}/* * Break out of an expect loop. */int dobreak(){ if (!inexpect) { s_error("script \"%s\" line %d: break outside of expect\r\n", curenv->scriptname, thisline->lineno); exit(1); } return(BREAK);}/* * Call another script! */int docall(text)char *text;{ struct line *oldline; struct env *oldenv; int er; if (*text == 0) syntaxerr("(argument expected)"); if (inexpect) { s_error("script \"%s\" line %d: call inside expect\r\n", curenv->scriptname); exit(1); } oldline = thisline; oldenv = curenv; if ((er = execscript(text)) != 0) exit(er); freemem(); thisline = oldline; curenv = oldenv; return(0);} /* KEYWORDS */struct kw { char *command; int (*fn)();} keywords[] = { { "expect", expect }, { "send", dosend }, { "!", shell }, { "goto", dogoto }, { "gosub", dogosub }, { "return", doreturn }, { "exit", doexit }, { "print", print }, { "set", doset }, { "inc", doinc }, { "dec", dodec }, { "if", doif }, { "timeout", dotimeout }, { "verbose", doverbose }, { "sleep", dosleep }, { "break", dobreak }, { "call", docall }, { (char *)0, (int(*)())0 },}; /* * Execute one line. */int s_exec(text)char *text;{ char *w; struct kw *k; w = getword(&text); /* If it is a label or a comment, skip it. */ if (w == CNULL || *w == '#' || w[strlen(w) - 1] == ':') return(OK); /* See which command it is. */ for(k = keywords; k->command; k++) if (!strcmp(w, k->command)) break; /* Command not found? */ if (k->command == (char *)NULL) { s_error("script \"%s\" line %d: unknown command \"%s\"\r\n", curenv->scriptname, thisline->lineno, w); exit(1); } return((*(k->fn))(text));}/* * Run the script by continously executing "thisline". */int execscript(s)char *s;{ struct env env; int ret; curenv = &env; curenv->lines = LNULL; curenv->vars = VNULL; curenv->verbose = 1; curenv->scriptname = s; if (readscript(s) < 0) { freemem(); return(ERR); } signal(SIGALRM, myclock); alarm(1); if (setjmp(curenv->ebuf) == 0) { thisline = curenv->lines; while(thisline != LNULL && (ret == s_exec(thisline->line)) != ERR) thisline = thisline->next; } else ret = curenv->exstat ? ERR : 0; return(ret);}int main(argc, argv)int argc;char **argv;{ signal(SIGHUP, SIG_IGN); init_env(); if (argc < 2) { s_error("Usage: runscript <scriptfile>\r\n"); return(1); } return(execscript(argv[1]));}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -