SCP: Allow command files to contain UTF-8 data.
- Ignore a UTF_BOM sequence at the beginning of command files. - Provide a sim_isspace() which makes sure that isspace only considers the character being examined as an unsigned char.
This commit is contained in:
parent
fe43187cde
commit
256bbdddc9
2 changed files with 31 additions and 23 deletions
53
scp.c
53
scp.c
|
@ -2629,7 +2629,7 @@ errabort = sim_switches & SWMASK ('E'); /* -e means abort on err
|
||||||
c = fcptr;
|
c = fcptr;
|
||||||
do_arg[10] = NULL; /* make sure the argument list always ends with a NULL */
|
do_arg[10] = NULL; /* make sure the argument list always ends with a NULL */
|
||||||
for (nargs = 0; nargs < 10; ) { /* extract arguments */
|
for (nargs = 0; nargs < 10; ) { /* extract arguments */
|
||||||
while (isspace (*c)) /* skip blanks */
|
while (sim_isspace (*c)) /* skip blanks */
|
||||||
c++;
|
c++;
|
||||||
if (*c == 0) /* all done? */
|
if (*c == 0) /* all done? */
|
||||||
do_arg [nargs++] = NULL; /* null argument */
|
do_arg [nargs++] = NULL; /* null argument */
|
||||||
|
@ -2638,7 +2638,7 @@ for (nargs = 0; nargs < 10; ) { /* extract arguments */
|
||||||
quote = *c++;
|
quote = *c++;
|
||||||
else quote = 0;
|
else quote = 0;
|
||||||
do_arg[nargs++] = c; /* save start */
|
do_arg[nargs++] = c; /* save start */
|
||||||
while (*c && (quote ? (*c != quote) : !isspace (*c)))
|
while (*c && (quote ? (*c != quote) : !sim_isspace (*c)))
|
||||||
c++;
|
c++;
|
||||||
if (*c) /* term at quote/spc */
|
if (*c) /* term at quote/spc */
|
||||||
*c++ = 0;
|
*c++ = 0;
|
||||||
|
@ -2867,7 +2867,7 @@ tmnow = localtime(&now);
|
||||||
tmpbuf = (char *)malloc(instr_size);
|
tmpbuf = (char *)malloc(instr_size);
|
||||||
op = tmpbuf;
|
op = tmpbuf;
|
||||||
oend = tmpbuf + instr_size - 2;
|
oend = tmpbuf + instr_size - 2;
|
||||||
while (isspace (*ip)) /* skip leading spaces */
|
while (sim_isspace (*ip)) /* skip leading spaces */
|
||||||
*op++ = *ip++;
|
*op++ = *ip++;
|
||||||
istart = ip;
|
istart = ip;
|
||||||
for (; *ip && (op < oend); ) {
|
for (; *ip && (op < oend); ) {
|
||||||
|
@ -3182,7 +3182,7 @@ if (*cptr == '"') { /* quoted string compari
|
||||||
if (!*tptr)
|
if (!*tptr)
|
||||||
return SCPE_2FARG;
|
return SCPE_2FARG;
|
||||||
cptr += strlen (gbuf);
|
cptr += strlen (gbuf);
|
||||||
while (isspace (*cptr)) /* skip spaces */
|
while (sim_isspace (*cptr)) /* skip spaces */
|
||||||
++cptr;
|
++cptr;
|
||||||
get_glyph (cptr, op, '"');
|
get_glyph (cptr, op, '"');
|
||||||
for (optr = compare_ops; optr->op; optr++)
|
for (optr = compare_ops; optr->op; optr++)
|
||||||
|
@ -3191,7 +3191,7 @@ if (*cptr == '"') { /* quoted string compari
|
||||||
if (!optr->op)
|
if (!optr->op)
|
||||||
return sim_messagef (SCPE_ARG, "Invalid operator: %s\n", op);
|
return sim_messagef (SCPE_ARG, "Invalid operator: %s\n", op);
|
||||||
cptr += strlen (op);
|
cptr += strlen (op);
|
||||||
while (isspace (*cptr)) /* skip spaces */
|
while (sim_isspace (*cptr)) /* skip spaces */
|
||||||
++cptr;
|
++cptr;
|
||||||
cptr = (char *)get_glyph_gen (cptr, gbuf2, 0, (sim_switches & SWMASK ('I')), TRUE, '\\');/* get second string */
|
cptr = (char *)get_glyph_gen (cptr, gbuf2, 0, (sim_switches & SWMASK ('I')), TRUE, '\\');/* get second string */
|
||||||
if (*cptr) { /* more? */
|
if (*cptr) { /* more? */
|
||||||
|
@ -3454,7 +3454,7 @@ while (1) {
|
||||||
if (*cptr == 0) continue; /* ignore blank */
|
if (*cptr == 0) continue; /* ignore blank */
|
||||||
if (*cptr != ':') continue; /* ignore non-labels */
|
if (*cptr != ':') continue; /* ignore non-labels */
|
||||||
++cptr; /* skip : */
|
++cptr; /* skip : */
|
||||||
while (isspace (*cptr)) ++cptr; /* skip blanks */
|
while (sim_isspace (*cptr)) ++cptr; /* skip blanks */
|
||||||
cptr = get_glyph (cptr, gbuf, 0); /* get label glyph */
|
cptr = get_glyph (cptr, gbuf, 0); /* get label glyph */
|
||||||
if (0 == strcmp(gbuf, gbuf1)) {
|
if (0 == strcmp(gbuf, gbuf1)) {
|
||||||
sim_brk_clract (); /* goto defangs current actions */
|
sim_brk_clract (); /* goto defangs current actions */
|
||||||
|
@ -3735,7 +3735,7 @@ else {
|
||||||
if (mptr->mstring && (MATCH_CMD (gbuf, mptr->mstring) == 0)) {
|
if (mptr->mstring && (MATCH_CMD (gbuf, mptr->mstring) == 0)) {
|
||||||
dptr = sim_dflt_dev;
|
dptr = sim_dflt_dev;
|
||||||
cptr = svptr;
|
cptr = svptr;
|
||||||
while (isspace(*cptr))
|
while (sim_isspace(*cptr))
|
||||||
++cptr;
|
++cptr;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -4002,7 +4002,7 @@ else {
|
||||||
dptr = sim_dflt_dev;
|
dptr = sim_dflt_dev;
|
||||||
lvl = MTAB_VDV; /* device match */
|
lvl = MTAB_VDV; /* device match */
|
||||||
cptr = svptr;
|
cptr = svptr;
|
||||||
while (isspace(*cptr))
|
while (sim_isspace(*cptr))
|
||||||
++cptr;
|
++cptr;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -4685,7 +4685,7 @@ if (*cptr == '\0')
|
||||||
cptr = "./*";
|
cptr = "./*";
|
||||||
strcpy (WildName, cptr);
|
strcpy (WildName, cptr);
|
||||||
cptr = WildName;
|
cptr = WildName;
|
||||||
while (strlen(WildName) && isspace(WildName[strlen(WildName)-1]))
|
while (strlen(WildName) && sim_isspace(WildName[strlen(WildName)-1]))
|
||||||
WildName[strlen(WildName)-1] = '\0';
|
WildName[strlen(WildName)-1] = '\0';
|
||||||
if ((!stat (WildName, &filestat)) && (filestat.st_mode & S_IFDIR))
|
if ((!stat (WildName, &filestat)) && (filestat.st_mode & S_IFDIR))
|
||||||
strcat (WildName, "/*");
|
strcat (WildName, "/*");
|
||||||
|
@ -4697,7 +4697,7 @@ if ((*cptr != '/') || (0 == memcmp (cptr, "./", 2)) || (0 == memcmp (cptr, "../"
|
||||||
#endif
|
#endif
|
||||||
strcat (WholeName, "/");
|
strcat (WholeName, "/");
|
||||||
strcat (WholeName, cptr);
|
strcat (WholeName, cptr);
|
||||||
while (strlen(WholeName) && isspace(WholeName[strlen(WholeName)-1]))
|
while (strlen(WholeName) && sim_isspace(WholeName[strlen(WholeName)-1]))
|
||||||
WholeName[strlen(WholeName)-1] = '\0';
|
WholeName[strlen(WholeName)-1] = '\0';
|
||||||
}
|
}
|
||||||
while ((c = strstr (WholeName, "/./")))
|
while ((c = strstr (WholeName, "/./")))
|
||||||
|
@ -6814,7 +6814,9 @@ for (tptr = cptr; tptr < (cptr + size); tptr++) { /* remove cr or nl */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (isspace (*cptr)) /* trim leading spc */
|
if (0 == memcmp (cptr, "\xEF\xBB\xBF", 3)) /* Skip/ignore UTF8_BOM */
|
||||||
|
memmove (cptr, cptr + 3, strlen (cptr + 3));
|
||||||
|
while (sim_isspace (*cptr)) /* trim leading spc */
|
||||||
cptr++;
|
cptr++;
|
||||||
if ((*cptr == ';') || (*cptr == '#')) { /* ignore comment */
|
if ((*cptr == ';') || (*cptr == '#')) { /* ignore comment */
|
||||||
if (sim_do_echo) /* echo comments if -v */
|
if (sim_do_echo) /* echo comments if -v */
|
||||||
|
@ -6854,7 +6856,7 @@ t_bool escaping = FALSE;
|
||||||
char quote_char = 0;
|
char quote_char = 0;
|
||||||
|
|
||||||
while ((*iptr != 0) &&
|
while ((*iptr != 0) &&
|
||||||
((quote && quoting) || ((isspace (*iptr) == 0) && (*iptr != mchar)))) {
|
((quote && quoting) || ((sim_isspace (*iptr) == 0) && (*iptr != mchar)))) {
|
||||||
if (quote) {
|
if (quote) {
|
||||||
if (quoting) {
|
if (quoting) {
|
||||||
if (!escaping) {
|
if (!escaping) {
|
||||||
|
@ -6882,7 +6884,7 @@ while ((*iptr != 0) &&
|
||||||
*optr = 0;
|
*optr = 0;
|
||||||
if (mchar && (*iptr == mchar)) /* skip terminator */
|
if (mchar && (*iptr == mchar)) /* skip terminator */
|
||||||
iptr++;
|
iptr++;
|
||||||
while (isspace (*iptr)) /* absorb spaces */
|
while (sim_isspace (*iptr)) /* absorb spaces */
|
||||||
iptr++;
|
iptr++;
|
||||||
return iptr;
|
return iptr;
|
||||||
}
|
}
|
||||||
|
@ -6915,11 +6917,16 @@ char *sim_trim_endspc (char *cptr)
|
||||||
char *tptr;
|
char *tptr;
|
||||||
|
|
||||||
tptr = cptr + strlen (cptr);
|
tptr = cptr + strlen (cptr);
|
||||||
while ((--tptr >= cptr) && isspace (*tptr))
|
while ((--tptr >= cptr) && sim_isspace (*tptr))
|
||||||
*tptr = 0;
|
*tptr = 0;
|
||||||
return cptr;
|
return cptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int sim_isspace (char c)
|
||||||
|
{
|
||||||
|
return isspace ((unsigned char)c);
|
||||||
|
}
|
||||||
|
|
||||||
/* get_yn yes/no question
|
/* get_yn yes/no question
|
||||||
|
|
||||||
Inputs:
|
Inputs:
|
||||||
|
@ -6963,7 +6970,7 @@ val = strtotv (cptr, &tptr, radix);
|
||||||
if ((cptr == tptr) || (val > max))
|
if ((cptr == tptr) || (val > max))
|
||||||
*status = SCPE_ARG;
|
*status = SCPE_ARG;
|
||||||
else {
|
else {
|
||||||
while (isspace (*tptr)) tptr++;
|
while (sim_isspace (*tptr)) tptr++;
|
||||||
if (*tptr != 0)
|
if (*tptr != 0)
|
||||||
*status = SCPE_ARG;
|
*status = SCPE_ARG;
|
||||||
}
|
}
|
||||||
|
@ -7477,7 +7484,7 @@ int32 sw;
|
||||||
if (*cptr != '-')
|
if (*cptr != '-')
|
||||||
return 0;
|
return 0;
|
||||||
sw = 0;
|
sw = 0;
|
||||||
for (cptr++; (isspace (*cptr) == 0) && (*cptr != 0); cptr++) {
|
for (cptr++; (sim_isspace (*cptr) == 0) && (*cptr != 0); cptr++) {
|
||||||
if (isalpha (*cptr) == 0)
|
if (isalpha (*cptr) == 0)
|
||||||
return -1;
|
return -1;
|
||||||
sw = sw | SWMASK (toupper (*cptr));
|
sw = sw | SWMASK (toupper (*cptr));
|
||||||
|
@ -7868,7 +7875,7 @@ uint32 c, digit;
|
||||||
*endptr = (char *)inptr; /* assume fails */
|
*endptr = (char *)inptr; /* assume fails */
|
||||||
if ((radix < 2) || (radix > 36))
|
if ((radix < 2) || (radix > 36))
|
||||||
return 0;
|
return 0;
|
||||||
while (isspace (*inptr)) /* bypass white space */
|
while (sim_isspace (*inptr)) /* bypass white space */
|
||||||
inptr++;
|
inptr++;
|
||||||
val = 0;
|
val = 0;
|
||||||
nodigit = 1;
|
nodigit = 1;
|
||||||
|
@ -8607,7 +8614,7 @@ size_t lnt;
|
||||||
|
|
||||||
if (sim_brk_act[sim_do_depth] == NULL) /* any action? */
|
if (sim_brk_act[sim_do_depth] == NULL) /* any action? */
|
||||||
return NULL;
|
return NULL;
|
||||||
while (isspace (*sim_brk_act[sim_do_depth])) /* skip spaces */
|
while (sim_isspace (*sim_brk_act[sim_do_depth])) /* skip spaces */
|
||||||
sim_brk_act[sim_do_depth]++;
|
sim_brk_act[sim_do_depth]++;
|
||||||
if (*sim_brk_act[sim_do_depth] == 0) { /* now empty? */
|
if (*sim_brk_act[sim_do_depth] == 0) { /* now empty? */
|
||||||
return sim_brk_clract ();
|
return sim_brk_clract ();
|
||||||
|
@ -8732,7 +8739,7 @@ if (*cptr == '[') {
|
||||||
if ((cptr == c1ptr) || (*c1ptr != ']'))
|
if ((cptr == c1ptr) || (*c1ptr != ']'))
|
||||||
return sim_messagef (SCPE_ARG, "Invalid Repeat count specification\n");
|
return sim_messagef (SCPE_ARG, "Invalid Repeat count specification\n");
|
||||||
cptr = (char *)(c1ptr + 1);
|
cptr = (char *)(c1ptr + 1);
|
||||||
while (isspace(*cptr))
|
while (sim_isspace(*cptr))
|
||||||
++cptr;
|
++cptr;
|
||||||
}
|
}
|
||||||
tptr = get_glyph (cptr, gbuf, ',');
|
tptr = get_glyph (cptr, gbuf, ',');
|
||||||
|
@ -8920,7 +8927,7 @@ if (ep->act) { /* replace old action? *
|
||||||
free (ep->act); /* deallocate */
|
free (ep->act); /* deallocate */
|
||||||
ep->act = NULL; /* now no action */
|
ep->act = NULL; /* now no action */
|
||||||
}
|
}
|
||||||
if (act) while (isspace(*act)) ++act; /* skip leading spaces in action string */
|
if (act) while (sim_isspace(*act)) ++act; /* skip leading spaces in action string */
|
||||||
if ((act != NULL) && (*act != 0)) { /* new action? */
|
if ((act != NULL) && (*act != 0)) { /* new action? */
|
||||||
char *newp = (char *) calloc (strlen (act)+1, sizeof (*act)); /* alloc buf */
|
char *newp = (char *) calloc (strlen (act)+1, sizeof (*act)); /* alloc buf */
|
||||||
if (newp == NULL) /* mem err? */
|
if (newp == NULL) /* mem err? */
|
||||||
|
@ -9803,7 +9810,7 @@ for (hblock = astrings; (htext = *hblock) != NULL; hblock++) {
|
||||||
const char *start;
|
const char *start;
|
||||||
|
|
||||||
help_where.line++;
|
help_where.line++;
|
||||||
if (isspace (*htext) || *htext == '+') {/* Topic text, indented topic text */
|
if (sim_isspace (*htext) || *htext == '+') {/* Topic text, indented topic text */
|
||||||
if (excluded) { /* Excluded topic text */
|
if (excluded) { /* Excluded topic text */
|
||||||
while (*htext && *htext != '\n')
|
while (*htext && *htext != '\n')
|
||||||
htext++;
|
htext++;
|
||||||
|
@ -9820,7 +9827,7 @@ for (hblock = astrings; (htext = *hblock) != NULL; hblock++) {
|
||||||
htext++;
|
htext++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (*htext && *htext != '\n' && isspace (*htext))
|
while (*htext && *htext != '\n' && sim_isspace (*htext))
|
||||||
htext++;
|
htext++;
|
||||||
if (!*htext) /* Empty after removing leading spaces */
|
if (!*htext) /* Empty after removing leading spaces */
|
||||||
break;
|
break;
|
||||||
|
@ -9922,7 +9929,7 @@ for (hblock = astrings; (htext = *hblock) != NULL; hblock++) {
|
||||||
FAIL (SCPE_ARG, Level not contiguous, htext); /* E.g. 1 3, not reasonable */
|
FAIL (SCPE_ARG, Level not contiguous, htext); /* E.g. 1 3, not reasonable */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (*htext && (*htext != '\n') && isspace (*htext))
|
while (*htext && (*htext != '\n') && sim_isspace (*htext))
|
||||||
htext++;
|
htext++;
|
||||||
if (!*htext || (*htext == '\n')) { /* Name missing */
|
if (!*htext || (*htext == '\n')) { /* Name missing */
|
||||||
FAIL (SCPE_ARG, Missing topic name, htext);
|
FAIL (SCPE_ARG, Missing topic name, htext);
|
||||||
|
|
1
scp.h
1
scp.h
|
@ -125,6 +125,7 @@ t_stat reset_all_p (uint32 start_device);
|
||||||
char *sim_dname (DEVICE *dptr);
|
char *sim_dname (DEVICE *dptr);
|
||||||
char *sim_uname (UNIT *dptr);
|
char *sim_uname (UNIT *dptr);
|
||||||
t_stat get_yn (char *ques, t_stat deflt);
|
t_stat get_yn (char *ques, t_stat deflt);
|
||||||
|
int sim_isspace (char c);
|
||||||
char *get_sim_opt (int32 opt, char *cptr, t_stat *st);
|
char *get_sim_opt (int32 opt, char *cptr, t_stat *st);
|
||||||
char *get_glyph (const char *iptr, char *optr, char mchar);
|
char *get_glyph (const char *iptr, char *optr, char mchar);
|
||||||
char *get_glyph_nc (const char *iptr, char *optr, char mchar);
|
char *get_glyph_nc (const char *iptr, char *optr, char mchar);
|
||||||
|
|
Loading…
Add table
Reference in a new issue