SCP: Revert pre-insertion of %n to be done during normal expansion.
This commit is contained in:
parent
2203608f4a
commit
f89a65ff2f
1 changed files with 45 additions and 73 deletions
118
scp.c
118
scp.c
|
@ -581,7 +581,7 @@ static int32 sim_show_message = 1; /* the message display s
|
||||||
static int32 sim_on_inherit = 0; /* the inherit status of on state and conditions when executing do files */
|
static int32 sim_on_inherit = 0; /* the inherit status of on state and conditions when executing do files */
|
||||||
static int32 sim_do_depth = 0;
|
static int32 sim_do_depth = 0;
|
||||||
static t_bool sim_cmd_echoed = FALSE; /* Command was emitted already prior to message output */
|
static t_bool sim_cmd_echoed = FALSE; /* Command was emitted already prior to message output */
|
||||||
|
static char **sim_exp_argv = NULL;
|
||||||
static int32 sim_on_check[MAX_DO_NEST_LVL+1];
|
static int32 sim_on_check[MAX_DO_NEST_LVL+1];
|
||||||
static char *sim_on_actions[MAX_DO_NEST_LVL+1][SCPE_MAX_ERR+2];
|
static char *sim_on_actions[MAX_DO_NEST_LVL+1][SCPE_MAX_ERR+2];
|
||||||
#define ON_SIGINT_ACTION (SCPE_MAX_ERR+1)
|
#define ON_SIGINT_ACTION (SCPE_MAX_ERR+1)
|
||||||
|
@ -3778,79 +3778,19 @@ return ap;
|
||||||
Omitted parameters result in null-string substitutions.
|
Omitted parameters result in null-string substitutions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void
|
|
||||||
_sub_args (char *instr, char *tmpbuf, size_t str_size, char *do_arg[])
|
|
||||||
{
|
|
||||||
char *ip, *op, *ap, *oend = tmpbuf + str_size - 2;
|
|
||||||
int i;
|
|
||||||
char rbuf[CBUFSIZE];
|
|
||||||
|
|
||||||
for (ip = instr, op = tmpbuf; *ip && (op < oend); ) {
|
|
||||||
if ((ip [0] == '\\') && /* literal escape? */
|
|
||||||
((ip [1] == '%') || (ip [1] == '\\'))) { /* and followed by '%' or '\'? */
|
|
||||||
*op++ = *ip++; /* copy \ */
|
|
||||||
*op++ = *ip++; /* copy escaped char */
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if ((*ip == '%') && /* %n = sub */
|
|
||||||
(sim_isdigit(ip[1]) || (ip[1] == '*'))) {
|
|
||||||
if ((ip[1] >= '0') && (ip[1] <= '9')) {
|
|
||||||
ap = do_arg[ip[1] - '0'];
|
|
||||||
for (i=0; i<ip[1] - '0'; ++i) /* make sure we're not past the list end */
|
|
||||||
if (do_arg[i] == NULL) {
|
|
||||||
ap = NULL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (ap) { /* non-null arg? */
|
|
||||||
while (*ap && (op < oend)) /* copy the argument */
|
|
||||||
*op++ = *ap++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else { /* it was %* */
|
|
||||||
memset (rbuf, '\0', sizeof(rbuf)); /* %1 ... %9 = sub */
|
|
||||||
ap = rbuf;
|
|
||||||
for (i=1; i<=9; ++i) {
|
|
||||||
if (do_arg[i] == NULL)
|
|
||||||
break;
|
|
||||||
else
|
|
||||||
if ((sizeof(rbuf)-strlen(rbuf)) < (2 + strlen(do_arg[i]))) {
|
|
||||||
if (strchr(do_arg[i], ' ')) { /* need to surround this argument with quotes */
|
|
||||||
char quote = '"';
|
|
||||||
if (strchr(do_arg[i], quote))
|
|
||||||
quote = '\'';
|
|
||||||
sprintf(&rbuf[strlen(rbuf)], "%s%c%s%c\"", (i != 1) ? " " : "", quote, do_arg[i], quote);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
sprintf(&rbuf[strlen(rbuf)], "%s%s", (i != 1) ? " " : "", do_arg[i]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ip = ip + 2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
*op++ = *ip++; /* literal character */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*op = 0; /* term buffer */
|
|
||||||
strcpy (instr, tmpbuf);
|
|
||||||
}
|
|
||||||
|
|
||||||
void sim_sub_args (char *instr, size_t instr_size, char *do_arg[])
|
void sim_sub_args (char *instr, size_t instr_size, char *do_arg[])
|
||||||
{
|
{
|
||||||
char gbuf[CBUFSIZE];
|
char gbuf[CBUFSIZE];
|
||||||
char *ip = instr, *op, *oend, *istart, *tmpbuf;
|
char *ip = instr, *op, *oend, *istart, *tmpbuf;
|
||||||
const char *ap;
|
const char *ap;
|
||||||
char rbuf[CBUFSIZE];
|
char rbuf[CBUFSIZE];
|
||||||
|
int i;
|
||||||
size_t instr_off = 0;
|
size_t instr_off = 0;
|
||||||
size_t outstr_off = 0;
|
size_t outstr_off = 0;
|
||||||
|
|
||||||
|
sim_exp_argv = do_arg;
|
||||||
clock_gettime(CLOCK_REALTIME, &cmd_time);
|
clock_gettime(CLOCK_REALTIME, &cmd_time);
|
||||||
tmpbuf = (char *)malloc(instr_size);
|
tmpbuf = (char *)malloc(instr_size);
|
||||||
/* directly insert %n arguments BEFORE substituting environment
|
|
||||||
and special variables */
|
|
||||||
_sub_args (instr, tmpbuf, instr_size, do_arg);
|
|
||||||
op = tmpbuf;
|
op = tmpbuf;
|
||||||
oend = tmpbuf + instr_size - 2;
|
oend = tmpbuf + instr_size - 2;
|
||||||
if (instr_size > sim_sub_instr_size) {
|
if (instr_size > sim_sub_instr_size) {
|
||||||
|
@ -3891,14 +3831,46 @@ for (; *ip && (op < oend); ) {
|
||||||
ip++; /* skip one */
|
ip++; /* skip one */
|
||||||
*op++ = *ip++; /* copy insert % */
|
*op++ = *ip++; /* copy insert % */
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
if ((*ip == '%') &&
|
if ((*ip == '%') &&
|
||||||
(sim_isalpha(ip[1]) || (ip[1] == '_'))) { /* sub env or special? */
|
(sim_isalnum(ip[1]) || (ip[1] == '*') || (ip[1] == '_'))) {/* sub? */
|
||||||
get_glyph_nc (ip+1, gbuf, '%'); /* get the literal name */
|
if ((ip[1] >= '0') && (ip[1] <= ('9'))) { /* %n = sub */
|
||||||
ap = _sim_get_env_special (gbuf, rbuf, sizeof (rbuf));
|
ap = do_arg[ip[1] - '0'];
|
||||||
ip += 1 + strlen (gbuf);
|
for (i=0; i<ip[1] - '0'; ++i) /* make sure we're not past the list end */
|
||||||
if (*ip == '%')
|
if (do_arg[i] == NULL) {
|
||||||
++ip;
|
ap = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ip = ip + 2;
|
||||||
|
}
|
||||||
|
else if (ip[1] == '*') { /* %1 ... %9 = sub */
|
||||||
|
memset (rbuf, '\0', sizeof(rbuf));
|
||||||
|
ap = rbuf;
|
||||||
|
for (i=1; i<=9; ++i)
|
||||||
|
if (do_arg[i] == NULL)
|
||||||
|
break;
|
||||||
|
else
|
||||||
|
if ((sizeof(rbuf)-strlen(rbuf)) < (2 + strlen(do_arg[i]))) {
|
||||||
|
if (strchr(do_arg[i], ' ')) { /* need to surround this argument with quotes */
|
||||||
|
char quote = '"';
|
||||||
|
if (strchr(do_arg[i], quote))
|
||||||
|
quote = '\'';
|
||||||
|
sprintf(&rbuf[strlen(rbuf)], "%s%c%s%c\"", (i != 1) ? " " : "", quote, do_arg[i], quote);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
sprintf(&rbuf[strlen(rbuf)], "%s%s", (i != 1) ? " " : "", do_arg[i]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
ip = ip + 2;
|
||||||
|
}
|
||||||
|
else { /* check environment variable or special variables */
|
||||||
|
get_glyph_nc (ip+1, gbuf, '%'); /* get the literal name */
|
||||||
|
ap = _sim_get_env_special (gbuf, rbuf, sizeof (rbuf));
|
||||||
|
ip += 1 + strlen (gbuf);
|
||||||
|
if (*ip == '%')
|
||||||
|
++ip;
|
||||||
|
}
|
||||||
if (ap) { /* non-null arg? */
|
if (ap) { /* non-null arg? */
|
||||||
while (*ap && (op < oend)) { /* copy the argument */
|
while (*ap && (op < oend)) { /* copy the argument */
|
||||||
sim_sub_instr_off[outstr_off++] = ip - instr;
|
sim_sub_instr_off[outstr_off++] = ip - instr;
|
||||||
|
@ -3906,7 +3878,7 @@ for (; *ip && (op < oend); ) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
if (ip == istart) { /* at beginning of input? */
|
if (ip == istart) { /* at beginning of input? */
|
||||||
get_glyph (istart, gbuf, 0); /* substitute initial token */
|
get_glyph (istart, gbuf, 0); /* substitute initial token */
|
||||||
ap = getenv(gbuf); /* if it is an environment variable name */
|
ap = getenv(gbuf); /* if it is an environment variable name */
|
||||||
|
@ -3925,8 +3897,6 @@ for (; *ip && (op < oend); ) {
|
||||||
sim_sub_instr_off[outstr_off++] = ip - instr;
|
sim_sub_instr_off[outstr_off++] = ip - instr;
|
||||||
*op++ = *ip++; /* literal character */
|
*op++ = *ip++; /* literal character */
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
*op = 0; /* term buffer */
|
*op = 0; /* term buffer */
|
||||||
sim_sub_instr_off[outstr_off] = 0;
|
sim_sub_instr_off[outstr_off] = 0;
|
||||||
|
@ -14011,6 +13981,7 @@ if (string[0] == '\0') {
|
||||||
snprintf (string, string_size - 1, "\"%s\"", data);
|
snprintf (string, string_size - 1, "\"%s\"", data);
|
||||||
return (*gptr == '\0');
|
return (*gptr == '\0');
|
||||||
}
|
}
|
||||||
|
sim_sub_args (string, string_size, sim_exp_argv);
|
||||||
*svalue = strtotsv(string + 1, &gptr, 0);
|
*svalue = strtotsv(string + 1, &gptr, 0);
|
||||||
return ((*gptr == '\"') && ((gptr - string) == (strlen (string) - 2)));
|
return ((*gptr == '\"') && ((gptr - string) == (strlen (string) - 2)));
|
||||||
}
|
}
|
||||||
|
@ -14096,6 +14067,7 @@ const char *sim_eval_expression (const char *cptr, t_svalue *value, t_bool paren
|
||||||
const char *iptr = cptr;
|
const char *iptr = cptr;
|
||||||
Stack *postfix = new_Stack (); /* for the postfix expression */
|
Stack *postfix = new_Stack (); /* for the postfix expression */
|
||||||
|
|
||||||
|
sim_debug (SIM_DBG_EXP_EVAL, sim_dflt_dev, "[Evaluate Expression: %s\n", cptr);
|
||||||
*value = 0;
|
*value = 0;
|
||||||
cptr = sim_into_postfix (postfix, cptr, stat, parens_required);
|
cptr = sim_into_postfix (postfix, cptr, stat, parens_required);
|
||||||
if (*stat != SCPE_OK) {
|
if (*stat != SCPE_OK) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue