1
0
mirror of https://github.com/simh/simh.git synced 2026-02-15 20:27:40 +00:00

SCP: Cleaned up help for EXPECT and SEND commands. Added optional case insensitive match option to regular expression EXPECT rules.

This commit is contained in:
Mark Pizzolato
2014-10-22 11:27:38 -07:00
parent 1413e762a4
commit 916bab3c2a
3 changed files with 110 additions and 14 deletions

110
scp.c
View File

@@ -1378,18 +1378,30 @@ ASSERT failure have several different actions:
"3Injecting Console Input\n"
" The SEND command provides a way to insert input into the console device of\n"
" a simulated system as if it was entered by a user.\n\n"
"++SEND {delay=nn,}\"<string>\" send input string into console\n\n"
"++SEND {after=nn,}{delay=nn,}\"<string>\"\n\n"
" The string argument must be delimited by quote characters. Quotes may\n"
" be either single or double but the opening and closing quote characters\n"
" must match. Data in the string may contain escaped character strings.\n\n"
" The SEND command can also insert input into any serial device on a\n"
" simulated system as if it was entered by a user.\n\n"
"++SEND <dev>:line {delay=nn,}\"<string>\"\n\n"
"++SEND <dev>:line {after=nn,}{delay=nn,}\"<string>\"\n\n"
"4Delay\n"
" Specifies a positive integer representing a minimal instruction delay\n"
" before and between characdters being sent. The value specified in a delay\n"
" argument persists across SEND commands. The delay parameter can be set by\n"
" itself with SEND DELAY=n\n"
" between characters being sent. The value specified in a delay\n"
" argument persists across SEND commands to the same device (console or\n"
" serial device). The delay parameter can be set by itself with\n\n"
"++SEND DELAY=n\n\n"
" The default value of the delay parameter is 1000.\n"
/***************** 80 character line width template *************************/
"4After\n"
" Specifies a positive integer representing a minimal number of instructions\n"
" which must execute before the first character in the string is sent.\n"
" The value specified as the after parameter persists across SEND commands\n"
" to the same device (console or serial device). The after parameter value\n"
" can be set by itself with:\n\n"
"++SEND AFTER=n\n\n"
" If the after parameter isn't explicitly set, it defaults to the value of\n"
" the delay parameter.\n"
"4Escaping String Data\n"
" The following character escapes are explicitly supported:\n"
" ++\\r Sends the ASCII Carriage Return character (Decimal value 13)\n"
@@ -1413,11 +1425,20 @@ ASSERT failure have several different actions:
"3Reacting To Console Output\n"
" The EXPECT command provides a way to stop execution and take actions\n"
" when specific output has been generated by the simulated system.\n"
" a simulated system as if it was entered by a user.\n\n"
"++EXPECT {dev:line} \"<string>\" {actioncommand {; actioncommand}...}\n\n"
"++EXPECT {dev:line} {HALTAFTER=n,}\"<string>\" {actioncommand {; actioncommand}...}\n\n"
" The string argument must be delimited by quote characters. Quotes may\n"
" be either single or double but the opening and closing quote characters\n"
" must match. Data in the string may contain escaped character strings.\n"
" must match. Data in the string may contain escaped character strings.\n\n"
" When expect rules are defined, they are evaluated agains recently\n"
" produced output as each character is output to the device. Since this\n"
" evaluation processing is done on each output character, rules matching\n"
" is not specifically line oriented. If line oriented matching is desired\n"
" then rules should be defined which contain the simulated system's line\n"
" ending character sequence (i.e. \"\r\n\").\n"
" Once data has matched any expect rule, that data is no longer eligible\n"
" to match other expect rules which may already be defined.\n"
" Data which is output prior to the definition of an expect rule is not\n"
" eligible to be matched against.\n"
/***************** 80 character line width template *************************/
"4Switches\n"
" Switches can be used to influence the behavior of EXPECT rules\n\n"
@@ -1429,8 +1450,43 @@ ASSERT failure have several different actions:
" If an expect rule is defined with the -c switch, it will cause all\n"
" pending expect rules on the current device to be cleared when the rule\n"
" matches data in the device output stream.\n"
"5-r\n"
" If an expect rule is defined with the -r switch, the string is interpreted\n"
" as a regular expression applied to the output data stream. This regular\n"
" expression may contain parentheses delimited sub-groups.\n\n"
/***************** 80 character line width template *************************/
#if defined (HAVE_PCREPOSIX_H)
" The syntax of the regular expressions available are those supported by\n"
" the Perl Compatible Regular Expression package (aka PCRE). As the name\n"
" implies, the syntax is generally the same as Perl regular expressions.\n"
" See http://perldoc.perl.org/perlre.html for more details\n"
#elif defined (HAVE_REGEX_H)
" The syntax of the regular expressions available are those supported by\n"
" your local system's Regular Expression library using the Extended POSIX\n"
" Regular Expressiona\n"
#else
" Regular expression support is not currently available on your environment.\n"
" This simulator could use regular expression support provided by the\n"
" Perl Compatible Regular Expression (PCRE) package if it was available\n"
" when you simulator was compiled.\n"
#endif
"5-i\n"
" If a regular expression expect rule is defined with the -i switch,\n"
" character matching for that expression will be case independent.\n"
" The -i switch is only valid for regular expression expect rules.\n"
"4Determining Which Output Matched\n"
" When an expect rule matches data in the output stream, the rule which\n"
" matched is recorded in the environment variable _EXPECT_MATCH_PATTERN.\n"
" If the expect rule was a regular expression rule, then the environment\n"
" variable _EXPECT_MATCH_GROUP_0 is set to the whole string which matched\n"
" and if the match pattern had any parentheses delimited sub-groups, the\n"
" environment variables _EXPECT_MATCH_PATTERN_1 thru _EXPECT_MATCH_PATTERN_n\n"
" are set to the values within the string which matched the respective\n"
" sub-groups.\n"
/***************** 80 character line width template *************************/
"4Escaping String Data\n"
" The following character escapes are explicitly supported:\n"
" The following character escapes are explicitly supported when NOT using\n"
" regular expression match patterns:\n"
" ++\\r Sends the ASCII Carriage Return character (Decimal value 13)\n"
" ++\\n Sends the ASCII Linefeed character (Decimal value 10)\n"
" ++\\f Sends the ASCII Formfeed character (Decimal value 12)\n"
@@ -1446,7 +1502,20 @@ ASSERT failure have several different actions:
" ++\\n{n{n}} where each n is an octal digit (0-7)\n"
" and hext character values of the form:\n"
" ++\\xh{h} where each h is a hex digit (0-9A-Fa-f)\n"
/***************** 80 character line width template *************************/
"4HaltAfter\n"
" Specifies the number of instructions which should be executed before\n"
" simulator instruction execution should stop. The default is to stop\n"
" executing instructions immediately (i.e. HALTAFTER=0).\n"
" The HaltAfter delay, once set, persists for all expect behaviors for\n"
" that device.\n"
" The HaltAfter parameter value can be set by itself with:\n\n"
"++EXPECT HALTAFTER=n\n\n"
" To avoid potentially unpredictable system hehavior that will happen\n"
" if multiple expect rules are in effect and a haltafter value is large\n"
" enough for more than one expect rule to match before an earlier haltafter\n"
" delay has expired, only a single EXPECT rule can be defined if a non-zero\n"
" HaltAfter parameter has been set.\n"
/***************** 80 character line width template *************************/
#define HLP_ASSERT "*Commands Executing_Command_Files Testing_Simulator_State"
"3Testing Simulator State\n"
" The ASSERT command tests a simulator state condition and halts command\n"
@@ -8340,7 +8409,7 @@ if ((*cptr != '"') && (*cptr != '\'')) {
cptr = get_glyph_quoted (cptr, gbuf, 0);
if (*cptr != '\0')
return SCPE_2MARG; /* No more arguments */
return sim_exp_set (exp, gbuf, cnt, after, sim_switches, cptr);
return sim_exp_set (exp, gbuf, cnt, (after ? after : exp->after), sim_switches, cptr);
}
/* Clear expect */
@@ -8452,7 +8521,7 @@ if (switches & EXP_TYP_REGEX) {
memset (&re, 0, sizeof(re));
memcpy (match_buf, match+1, strlen(match)-2); /* extract string without surrounding quotes */
match_buf[strlen(match)-2] = '\0';
res = regcomp (&re, (char *)match_buf, REG_EXTENDED);
res = regcomp (&re, (char *)match_buf, REG_EXTENDED | ((switches & EXP_TYP_REGEX_I) ? REG_ICASE : 0));
if (res) {
size_t err_size = regerror (res, &re, NULL, 0);
char *err_buf = calloc (err_size+1, 1);
@@ -8468,6 +8537,10 @@ if (switches & EXP_TYP_REGEX) {
}
#endif
else {
if (switches & EXP_TYP_REGEX_I) {
sim_printf ("Case independed matching is only valid for RegEx expect rules\n");
return SCPE_ARG|SCPE_NOMESSAGE;
}
if (SCPE_OK != sim_decode_quoted_string (match, match_buf, &match_size)) {
free (match_buf);
return SCPE_ARG;
@@ -8477,6 +8550,10 @@ free (match_buf);
ep = sim_exp_fnd (exp, match); /* present? */
if (ep) /* no, allocate */
sim_exp_clr_tab (exp, ep); /* clear it */
if (after && exp->size) {
sim_printf ("Multiple concurrent EXPECT rules aren't valid when a HALTAFTER parameter is non-zero\n");
return SCPE_ARG|SCPE_NOMESSAGE;
}
exp->rules = (EXPTAB *) realloc (exp->rules, sizeof (*exp->rules)*(exp->size + 1));
ep = &exp->rules[exp->size];
exp->size += 1;
@@ -8543,6 +8620,8 @@ if (ep->switches & EXP_TYP_CLEARALL)
fprintf (st, " -c");
if (ep->switches & EXP_TYP_REGEX)
fprintf (st, " -r");
if (ep->switches & EXP_TYP_REGEX_I)
fprintf (st, " -i");
fprintf (st, " %s", ep->match_pattern);
if (ep->cnt > 0)
fprintf (st, " [%d]", ep->cnt);
@@ -8603,7 +8682,7 @@ for (i=0; i < exp->size; i++) {
++regex_checks;
matches = calloc ((ep->regex.re_nsub + 1), sizeof(*matches));
exp->buf[exp->buf_ins] = '\0';
if (!regexec (&ep->regex, (char *)exp->buf, ep->regex.re_nsub + 1, matches, 0)) {
if (!regexec (&ep->regex, (char *)exp->buf, ep->regex.re_nsub + 1, matches, REG_NOTBOL|REG_NOTEOL)) {
size_t j;
char *buf = malloc (1 + exp->buf_ins);
@@ -8651,7 +8730,8 @@ if (exp->buf_ins == exp->buf_size) { /* At end of match buffe
/* When processing regular expressions, let the match buffer fill
up and then shuffle the buffer contents down by half the buffer size
so that the regular expression has a single contiguous buffer to
match against instead of the wrapping buffer which is used otherwise */
match against instead of the wrapping buffer paradigm which is
used when no regular expression rules are in effect */
memmove (exp->buf, &exp->buf[exp->buf_size/2], exp->buf_size-(exp->buf_size/2));
exp->buf_ins -= exp->buf_size/2;
}
@@ -8680,6 +8760,8 @@ if (i != exp->size) { /* Found? */
sim_exp_clrall (exp); /* delete all rules */
sim_activate (&sim_expect_unit, exp->after); /* schedule simulation stop when indicated */
}
/* Matched data is no longer available for future matching */
exp->buf_ins = 0;
}
return SCPE_OK;
}