mirror of
https://github.com/rcornwell/sims.git
synced 2026-05-09 08:59:47 +00:00
SCP: Updated to current.
This commit is contained in:
8
scp.c
8
scp.c
@@ -5644,12 +5644,14 @@ else {
|
||||
lvl = MTAB_VDV; /* device match */
|
||||
uptr = dptr->units; /* first unit */
|
||||
}
|
||||
if (*cptr == 0) /* must be more */
|
||||
if ((*cptr == 0) || (*cptr == ';') || (*cptr == '#')) /* must be more */
|
||||
return SCPE_2FARG;
|
||||
GET_SWITCHES (cptr); /* get more switches */
|
||||
|
||||
while (*cptr != 0) { /* do all mods */
|
||||
cptr = get_glyph (svptr = cptr, gbuf, ','); /* get modifier */
|
||||
if (0 == strcmp (gbuf, ";"))
|
||||
break;
|
||||
if ((cvptr = strchr (gbuf, '='))) /* = value? */
|
||||
*cvptr++ = 0;
|
||||
for (mptr = dptr->modifiers; mptr && (mptr->mask != 0); mptr++) {
|
||||
@@ -5902,7 +5904,7 @@ MTAB *mptr;
|
||||
SHTAB *shtb = NULL, *shptr;
|
||||
|
||||
GET_SWITCHES (cptr); /* get switches */
|
||||
if (*cptr == 0) /* must be more */
|
||||
if ((*cptr == 0) || (*cptr == ';') || (*cptr == '#')) /* must be more */
|
||||
return SCPE_2FARG;
|
||||
cptr = get_glyph (svptr = cptr, gbuf, 0); /* get next glyph */
|
||||
|
||||
@@ -5950,7 +5952,7 @@ else {
|
||||
}
|
||||
}
|
||||
|
||||
if (*cptr == 0) { /* now eol? */
|
||||
if ((*cptr == 0) || (*cptr == ';') || (*cptr == '#')) { /* now eol? */
|
||||
return (lvl == MTAB_VDV)?
|
||||
show_device (ofile, dptr, 0):
|
||||
show_unit (ofile, dptr, uptr, -1);
|
||||
|
||||
94
sim_fio.c
94
sim_fio.c
@@ -248,8 +248,25 @@ if ((0 != fstat (fileno (fp), &statb)) ||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void _sim_expand_homedir (const char *file, char *dest, size_t dest_size)
|
||||
static char *_sim_expand_homedir (const char *file, char *dest, size_t dest_size)
|
||||
{
|
||||
uint8 *without_quotes = NULL;
|
||||
uint32 dsize = 0;
|
||||
|
||||
errno = 0;
|
||||
if (((*file == '"') && (file[strlen (file) - 1] == '"')) ||
|
||||
((*file == '\'') && (file[strlen (file) - 1] == '\''))) {
|
||||
without_quotes = (uint8*)malloc (strlen (file) + 1);
|
||||
if (without_quotes == NULL)
|
||||
return NULL;
|
||||
if (SCPE_OK != sim_decode_quoted_string (file, without_quotes, &dsize)) {
|
||||
free (without_quotes);
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
file = (const char*)without_quotes;
|
||||
}
|
||||
|
||||
if (memcmp (file, "~/", 2) != 0)
|
||||
strlcpy (dest, file, dest_size);
|
||||
else {
|
||||
@@ -269,6 +286,8 @@ else {
|
||||
while ((strchr (dest, '\\') != NULL) && ((cptr = strchr (dest, '/')) != NULL))
|
||||
*cptr = '\\';
|
||||
}
|
||||
free (without_quotes);
|
||||
return dest;
|
||||
}
|
||||
|
||||
#if defined(_WIN32)
|
||||
@@ -283,7 +302,8 @@ int sim_stat (const char *fname, struct stat *stat_str)
|
||||
{
|
||||
char namebuf[PATH_MAX + 1];
|
||||
|
||||
_sim_expand_homedir (fname, namebuf, sizeof (namebuf));
|
||||
if (NULL == _sim_expand_homedir (fname, namebuf, sizeof (namebuf)))
|
||||
return -1;
|
||||
return stat (namebuf, stat_str);
|
||||
}
|
||||
|
||||
@@ -291,7 +311,8 @@ int sim_chdir(const char *path)
|
||||
{
|
||||
char pathbuf[PATH_MAX + 1];
|
||||
|
||||
_sim_expand_homedir (path, pathbuf, sizeof (pathbuf));
|
||||
if (NULL == _sim_expand_homedir (path, pathbuf, sizeof (pathbuf)))
|
||||
return -1;
|
||||
return chdir (pathbuf);
|
||||
}
|
||||
|
||||
@@ -299,7 +320,8 @@ int sim_mkdir(const char *path)
|
||||
{
|
||||
char pathbuf[PATH_MAX + 1];
|
||||
|
||||
_sim_expand_homedir (path, pathbuf, sizeof (pathbuf));
|
||||
if (NULL == _sim_expand_homedir (path, pathbuf, sizeof (pathbuf)))
|
||||
return -1;
|
||||
#if defined(_WIN32)
|
||||
return mkdir (pathbuf);
|
||||
#else
|
||||
@@ -311,7 +333,8 @@ int sim_rmdir(const char *path)
|
||||
{
|
||||
char pathbuf[PATH_MAX + 1];
|
||||
|
||||
_sim_expand_homedir (path, pathbuf, sizeof (pathbuf));
|
||||
if (NULL == _sim_expand_homedir (path, pathbuf, sizeof (pathbuf)))
|
||||
return -1;
|
||||
return rmdir (pathbuf);
|
||||
}
|
||||
|
||||
@@ -323,22 +346,9 @@ FILE* sim_fopen (const char *file, const char *mode)
|
||||
{
|
||||
FILE *f;
|
||||
char namebuf[PATH_MAX + 1];
|
||||
uint8 *without_quotes = NULL;
|
||||
uint32 dsize = 0;
|
||||
|
||||
if (((*file == '"') && (file[strlen (file) - 1] == '"')) ||
|
||||
((*file == '\'') && (file[strlen (file) - 1] == '\''))) {
|
||||
without_quotes = (uint8*)malloc (strlen (file) + 1);
|
||||
if (without_quotes == NULL)
|
||||
return NULL;
|
||||
if (SCPE_OK != sim_decode_quoted_string (file, without_quotes, &dsize)) {
|
||||
free (without_quotes);
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
file = (const char*)without_quotes;
|
||||
}
|
||||
_sim_expand_homedir (file, namebuf, sizeof (namebuf));
|
||||
if (NULL == _sim_expand_homedir (file, namebuf, sizeof (namebuf)))
|
||||
return NULL;
|
||||
#if defined (VMS)
|
||||
f = fopen (namebuf, mode, "ALQ=32", "DEQ=4096",
|
||||
"MBF=6", "MBC=127", "FOP=cbt,tef", "ROP=rah,wbh", "CTX=stm");
|
||||
@@ -347,7 +357,6 @@ f = fopen64 (namebuf, mode);
|
||||
#else
|
||||
f = fopen (namebuf, mode);
|
||||
#endif
|
||||
free (without_quotes);
|
||||
return f;
|
||||
}
|
||||
|
||||
@@ -481,8 +490,10 @@ t_stat sim_copyfile (const char *source_file, const char *dest_file, t_bool over
|
||||
{
|
||||
char sourcename[PATH_MAX + 1], destname[PATH_MAX + 1];
|
||||
|
||||
_sim_expand_homedir (source_file, sourcename, sizeof (sourcename));
|
||||
_sim_expand_homedir (dest_file, destname, sizeof (destname));
|
||||
if (NULL == _sim_expand_homedir (source_file, sourcename, sizeof (sourcename)))
|
||||
return sim_messagef (SCPE_ARG, "Error Copying - Problem Parsing Source Filename '%s'\n", source_file);
|
||||
if (NULL == _sim_expand_homedir (dest_file, destname, sizeof (destname)))
|
||||
return sim_messagef (SCPE_ARG, "Error Copying - Problem Parsing Destination Filename '%s'\n", dest_file);
|
||||
if (CopyFileA (sourcename, destname, !overwrite_existing))
|
||||
return SCPE_OK;
|
||||
return sim_messagef (SCPE_ARG, "Error Copying '%s' to '%s': %s\n", source_file, dest_file, sim_get_os_error_text (GetLastError ()));
|
||||
@@ -846,7 +857,6 @@ return getcwd (buf, buf_size);
|
||||
char *sim_filepath_parts (const char *filepath, const char *parts)
|
||||
{
|
||||
size_t tot_len = 0, tot_size = 0;
|
||||
char *tempfilepath = NULL;
|
||||
char *fullpath = NULL, *result = NULL;
|
||||
char *c, *name, *ext;
|
||||
char chr;
|
||||
@@ -855,21 +865,10 @@ char filesizebuf[32] = "";
|
||||
char filedatetimebuf[32] = "";
|
||||
char namebuf[PATH_MAX + 1];
|
||||
|
||||
/* Remove quotes if they're present */
|
||||
if (((*filepath == '\'') || (*filepath == '"')) &&
|
||||
(filepath[strlen (filepath) - 1] == *filepath)) {
|
||||
size_t temp_size = 1 + strlen (filepath);
|
||||
|
||||
tempfilepath = (char *)malloc (temp_size);
|
||||
if (tempfilepath == NULL)
|
||||
return NULL;
|
||||
strlcpy (tempfilepath, 1 + filepath, temp_size);
|
||||
tempfilepath[strlen (tempfilepath) - 1] = '\0';
|
||||
filepath = tempfilepath;
|
||||
}
|
||||
|
||||
/* Expand ~/ home directory */
|
||||
_sim_expand_homedir (filepath, namebuf, sizeof (namebuf));
|
||||
if (NULL == _sim_expand_homedir (filepath, namebuf, sizeof (namebuf)))
|
||||
return NULL;
|
||||
filepath = namebuf;
|
||||
|
||||
/* Check for full or current directory relative path */
|
||||
@@ -878,26 +877,20 @@ if ((filepath[1] == ':') ||
|
||||
(filepath[0] == '\\')){
|
||||
tot_len = 1 + strlen (filepath);
|
||||
fullpath = (char *)malloc (tot_len);
|
||||
if (fullpath == NULL) {
|
||||
free (tempfilepath);
|
||||
if (fullpath == NULL)
|
||||
return NULL;
|
||||
}
|
||||
strcpy (fullpath, filepath);
|
||||
}
|
||||
else { /* Need to prepend current directory */
|
||||
char dir[PATH_MAX+1] = "";
|
||||
char *wd = sim_getcwd(dir, sizeof (dir));
|
||||
|
||||
if (wd == NULL) {
|
||||
free (tempfilepath);
|
||||
if (wd == NULL)
|
||||
return NULL;
|
||||
}
|
||||
tot_len = 1 + strlen (filepath) + 1 + strlen (dir);
|
||||
fullpath = (char *)malloc (tot_len);
|
||||
if (fullpath == NULL) {
|
||||
free (tempfilepath);
|
||||
if (fullpath == NULL)
|
||||
return NULL;
|
||||
}
|
||||
strlcpy (fullpath, dir, tot_len);
|
||||
if ((dir[strlen (dir) - 1] != '/') && /* if missing a trailing directory separator? */
|
||||
(dir[strlen (dir) - 1] != '\\'))
|
||||
@@ -935,7 +928,7 @@ if (ext == NULL)
|
||||
ext = name + strlen (name);
|
||||
tot_size = 0;
|
||||
if (*parts == '\0') /* empty part specifier means strip only quotes */
|
||||
tot_size = strlen (tempfilepath);
|
||||
tot_size = strlen (filepath);
|
||||
if (strchr (parts, 't') || /* modification time or */
|
||||
strchr (parts, 'z')) { /* or size requested? */
|
||||
struct stat filestat;
|
||||
@@ -1006,7 +999,6 @@ for (p = parts; *p; p++) {
|
||||
}
|
||||
}
|
||||
free (fullpath);
|
||||
free (tempfilepath);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -1019,7 +1011,8 @@ WIN32_FIND_DATAA File;
|
||||
struct stat filestat;
|
||||
char WildName[PATH_MAX + 1];
|
||||
|
||||
_sim_expand_homedir (cptr, WildName, sizeof (WildName));
|
||||
if (NULL == _sim_expand_homedir (cptr, WildName, sizeof (WildName)))
|
||||
return SCPE_ARG;
|
||||
cptr = WildName;
|
||||
sim_trim_endspc (WildName);
|
||||
if ((hFind = FindFirstFileA (cptr, &File)) != INVALID_HANDLE_VALUE) {
|
||||
@@ -1082,7 +1075,8 @@ char DirName[PATH_MAX + 1], WholeName[PATH_MAX + 1], WildName[PATH_MAX + 1], Mat
|
||||
memset (DirName, 0, sizeof(DirName));
|
||||
memset (WholeName, 0, sizeof(WholeName));
|
||||
memset (MatchName, 0, sizeof(MatchName));
|
||||
_sim_expand_homedir (cptr, WildName, sizeof (WildName));
|
||||
if (NULL == _sim_expand_homedir (cptr, WildName, sizeof (WildName)))
|
||||
return SCPE_ARG;
|
||||
cptr = WildName;
|
||||
sim_trim_endspc (WildName);
|
||||
c = sim_filepath_parts (cptr, "f");
|
||||
|
||||
242
sim_tmxr.c
242
sim_tmxr.c
@@ -5146,117 +5146,157 @@ return SCPE_OK;
|
||||
|
||||
/* Set the line connection order.
|
||||
|
||||
Example command for eight-line multiplexer:
|
||||
This validation routine is called to set the connection order for the
|
||||
multiplexer whose TMXR pointer is passed in the "desc" parameter. It parses
|
||||
the line order list, specified by the "cptr" parameter, of commands such as:
|
||||
|
||||
SET <dev> LINEORDER=1;5;2-4;7
|
||||
SET <dev> LINEORDER=4-7
|
||||
SET <dev> LINEORDER=1;5;2-4;7;ALL
|
||||
SET <dev> LINEORDER=ALL
|
||||
|
||||
Resulting connection order: 1,5,2,3,4,7,0,6.
|
||||
Assuming an 8-channel multiplexer, the first form sets the connection order
|
||||
to line numbers 4, 5, 6, and 7. The remaining lines will not be connected; a
|
||||
connection attempt will be refused with "All connections busy." The second
|
||||
form sets the connection order to line 1, 5, 2, 3, 4, 7, 0, and 6. The
|
||||
trailing "ALL" parameter causes any unspecified lines to be added to the
|
||||
connection order in ascending value. The third form sets the order to lines
|
||||
0-7, which is the default order in the absence of a line connection order
|
||||
array.
|
||||
|
||||
Parameters:
|
||||
- uptr = (not used)
|
||||
- val = (not used)
|
||||
- cptr = pointer to first character of range specification
|
||||
- desc = pointer to multiplexer's TMXR structure
|
||||
The range of accepted line numbers, including those implied by "ALL", can be
|
||||
restricted by specifying a non-zero "val" parameter, with the upper 16 bits
|
||||
specifying the maximum line number, and the lower 16 bits specifying the
|
||||
minimum line number. If a minimum is specified but a maximum is not (i.e.,
|
||||
is zero), the maximum is the last line number defined by the multiplexer
|
||||
descriptor.
|
||||
|
||||
On entry, cptr points to the value portion of the command string, which may
|
||||
be either a semicolon-separated list of line ranges or the keyword ALL.
|
||||
The "uptr" parameter is not used.
|
||||
|
||||
On entry, "cptr" points to the value portion of the command string, which may
|
||||
be either a semicolon-separated list of line ranges or the keyword "ALL". If
|
||||
"ALL" is specified, it must be the last (or only) item in the list.
|
||||
|
||||
If a line connection order array is not defined in the multiplexer
|
||||
descriptor, the command is rejected. If the specified range encompasses all
|
||||
of the lines, the first value of the connection order array is set to -1 to
|
||||
descriptor, or a line range string is not present, or the optional minimum
|
||||
and maximum restrictions in the "val" parameter are not valid, the command is
|
||||
rejected. If the specified range encompasses all of the lines defined by the
|
||||
multiplexer, the first value of the connection order array is set to -1 to
|
||||
indicate sequential connection order. Otherwise, the line values in the
|
||||
array are set to the order specified by the command string. All values are
|
||||
populated, first with those explicitly specified in the command string, and
|
||||
then in ascending sequence with those not specified.
|
||||
array are set to the order specified by the command string. If fewer values
|
||||
are supplied than there are lines supported by the device, and the final
|
||||
parameter is not ALL, the remaining lines will be inaccessible and are
|
||||
indicated by a -1 value after the last specified value.
|
||||
|
||||
If an error occurs, the original line order is not disturbed.
|
||||
*/
|
||||
|
||||
t_stat tmxr_set_lnorder (UNIT *uptr, int32 val, CONST char *carg, void *desc)
|
||||
t_stat tmxr_set_lnorder (UNIT *uptr, int32 val, CONST char *cptr, void *desc)
|
||||
{
|
||||
TMXR *mp = (TMXR *) desc;
|
||||
char *tbuf;
|
||||
char *tptr;
|
||||
CONST char *cptr;
|
||||
t_addr low, high, max = (t_addr) mp->lines - 1;
|
||||
int32 *list;
|
||||
TMXR *mp = (TMXR *) desc;
|
||||
char *tbuf = NULL;
|
||||
char *tptr;
|
||||
t_addr low, high, min, max;
|
||||
int32 *list;
|
||||
t_bool *set;
|
||||
uint32 line, idx = 0;
|
||||
uint32 line, idx;
|
||||
t_addr lncount = (t_addr) (mp->lines - 1);
|
||||
t_stat result = SCPE_OK;
|
||||
|
||||
if (mp->lnorder == NULL) /* line connection order undefined? */
|
||||
return SCPE_NXPAR; /* "Non-existent parameter" error */
|
||||
if (mp->lnorder == NULL) /* if the connection order array is not defined */
|
||||
return SCPE_NXPAR; /* then report a "Non-existent parameter" error */
|
||||
|
||||
else if ((carg == NULL) || (*carg == '\0')) /* line range not supplied? */
|
||||
return SCPE_MISVAL; /* "Missing value" error */
|
||||
else if ((cptr == NULL) || (*cptr == '\0')) /* otherwise if a line range was not supplied */
|
||||
return SCPE_MISVAL; /* then report a "Missing value" error */
|
||||
|
||||
list = (int32 *) calloc (mp->lines, sizeof (int32)); /* allocate new line order array */
|
||||
else { /* otherwise */
|
||||
min = (t_addr) (val & 0xFFFF); /* split the restriction into */
|
||||
max = (t_addr) ((val >> 16) & 0xFFFF); /* minimum and maximum line numbers */
|
||||
|
||||
if (list == NULL) /* allocation failed? */
|
||||
return SCPE_MEM; /* report it */
|
||||
if (max == 0) /* if the maximum line number isn't specified */
|
||||
max = lncount; /* then use the defined maximum */
|
||||
|
||||
set = (t_bool *) calloc (mp->lines, sizeof (t_bool)); /* allocate line set tracking array */
|
||||
|
||||
if (set == NULL) { /* allocation failed? */
|
||||
free (list); /* free successful list allocation */
|
||||
return SCPE_MEM; /* report it */
|
||||
if (min > lncount || max > lncount || min > max) /* if the restriction isn't valid */
|
||||
return SCPE_IERR; /* then report an "Internal error" */
|
||||
}
|
||||
|
||||
tbuf = (char *) calloc (strlen(carg)+2, sizeof(*carg));
|
||||
strcpy (tbuf, carg);
|
||||
list = (int32 *) calloc (mp->lines, sizeof (int32)); /* allocate the new line order array */
|
||||
|
||||
if (list == NULL) /* if the allocation failed */
|
||||
return SCPE_MEM; /* then report a "Memory exhausted" error */
|
||||
|
||||
set = (t_bool *) calloc (mp->lines, sizeof (t_bool)); /* allocate the line set tracking array */
|
||||
|
||||
if (set == NULL) { /* if the allocation failed */
|
||||
free (list); /* then free the successful list allocation */
|
||||
return SCPE_MEM; /* and report a "Memory exhausted" error */
|
||||
}
|
||||
|
||||
tbuf = (char *) calloc (strlen(cptr)+2, sizeof(*cptr));
|
||||
if (tbuf == NULL) { /* if the allocation failed */
|
||||
free (tbuf); /* then free the successful list allocation */
|
||||
return SCPE_MEM; /* and report a "Memory exhausted" error */
|
||||
}
|
||||
|
||||
strcpy (tbuf, cptr);
|
||||
tptr = tbuf + strlen (tbuf); /* append a semicolon */
|
||||
*tptr++ = ';'; /* to the command string */
|
||||
*tptr = '\0'; /* to make parsing easier for get_range */
|
||||
cptr = tbuf;
|
||||
|
||||
while (*cptr) { /* parse command string */
|
||||
cptr = get_range (NULL, cptr, &low, &high, 10, max, ';');/* get a line range */
|
||||
idx = 0; /* initialize the index of ordered values */
|
||||
|
||||
if (cptr == NULL) { /* parsing error? */
|
||||
result = SCPE_ARG; /* "Invalid argument" error */
|
||||
break;
|
||||
while (*cptr != '\0') { /* while characters remain in the command string */
|
||||
if (strncasecmp (cptr, "ALL;", 4) == 0) { /* if the parameter is "ALL" */
|
||||
if (val != 0 || idx > 0 && idx <= max) /* then if some lines are restrictied or unspecified */
|
||||
for (line = (uint32) min; line <= max; line++) /* then fill them in sequentially */
|
||||
if (set [line] == FALSE) /* setting each unspecified line */
|
||||
list [idx++] = line; /* into the line order */
|
||||
|
||||
cptr = cptr + 4; /* advance past "ALL" and the trailing semicolon */
|
||||
|
||||
if (*cptr != '\0') /* if "ALL" is not the last parameter */
|
||||
result = sim_messagef (SCPE_2MARG, /* then report extraneous items */
|
||||
"Too many args: %s\n", cptr);
|
||||
|
||||
break; /* "ALL" terminates the order list */
|
||||
}
|
||||
|
||||
else if ((low > max) || (high > max)) { /* line out of range? */
|
||||
result = SCPE_SUB; /* "Subscript out of range" error */
|
||||
break;
|
||||
cptr = get_range (NULL, cptr, &low, &high, 10, max, ';'); /* get a line range */
|
||||
|
||||
if (cptr == NULL) { /* if a parsing error occurred */
|
||||
result = SCPE_ARG; /* then report an invalid argument */
|
||||
break; /* and terminate the parse */
|
||||
}
|
||||
|
||||
else if ((low == 0) && (high == max)) { /* entire line range specified? */
|
||||
list [0] = -1; /* set sequential order flag */
|
||||
idx = (uint32) max + 1; /* indicate no fill-in needed */
|
||||
break;
|
||||
else if (low < min || low > max || high > max) { /* otherwise if the line number is invalid */
|
||||
result = SCPE_SUB; /* then report the subscript is out of range */
|
||||
break; /* and terminate the parse */
|
||||
}
|
||||
|
||||
else
|
||||
for (line = (uint32) low; line <= (uint32) high; line++) /* see if previously specified */
|
||||
if (set [line] == FALSE) { /* not already specified? */
|
||||
set [line] = TRUE; /* now it is */
|
||||
list [idx] = line; /* add line to connection order */
|
||||
idx = idx + 1; /* bump "specified" count */
|
||||
else /* otherwise it's a valid range */
|
||||
for (line = (uint32) low; line <= high; line++) /* so add the line(s) to the order */
|
||||
if (set [line] == FALSE) { /* if the line number has not been specified */
|
||||
set [line] = TRUE; /* then now it is */
|
||||
list [idx++] = line; /* and add it to the connection order */
|
||||
}
|
||||
}
|
||||
|
||||
if (result == SCPE_OK) { /* assignment successful? */
|
||||
if (idx <= max) /* any lines not specified? */
|
||||
for (line = 0; line <= max; line++) /* fill them in sequentially */
|
||||
if (set [line] == FALSE) { /* specified? */
|
||||
list [idx] = line; /* no, so add it */
|
||||
idx = idx + 1;
|
||||
}
|
||||
if (result == SCPE_OK) { /* if the assignment succeeded */
|
||||
if (idx <= max) /* then if any lines were not specified */
|
||||
list [idx] = -1; /* then terminate the order list after the last one */
|
||||
|
||||
memcpy (mp->lnorder, list, mp->lines * sizeof (int32)); /* copy working array to connection array */
|
||||
memcpy (mp->lnorder, list, /* copy the working array to the connection array */
|
||||
mp->lines * sizeof (int32));
|
||||
}
|
||||
|
||||
free (list); /* free list allocation */
|
||||
free (set); /* free set allocation */
|
||||
free (tbuf); /* free arg copy with ; */
|
||||
free (list); /* free the list allocation */
|
||||
free (set); /* and the set allocation */
|
||||
free (tbuf); /* and the arg copy with ; */
|
||||
|
||||
return result;
|
||||
return result; /* return the status */
|
||||
}
|
||||
|
||||
|
||||
/* Show line connection order.
|
||||
/* Show the line connection order.
|
||||
|
||||
Parameters:
|
||||
- st = stream on which output is to be written
|
||||
@@ -5268,7 +5308,8 @@ return result;
|
||||
command is rejected. If the first value of the connection order array is set
|
||||
to -1, then the connection order is sequential. Otherwise, the line values
|
||||
in the array are printed as a semicolon-separated list. Ranges are printed
|
||||
where possible to shorten the output.
|
||||
where possible to shorten the output. A -1 value within the array indicates
|
||||
the end of the order list.
|
||||
*/
|
||||
|
||||
t_stat tmxr_show_lnorder (FILE *st, UNIT *uptr, int32 val, CONST void *desc)
|
||||
@@ -5287,7 +5328,7 @@ if (*iptr < 0) /* sequential order indi
|
||||
else {
|
||||
low = last = *iptr++; /* set first line value */
|
||||
|
||||
for (j = 1; j <= mp->lines; j++) { /* print remaining lines in order list */
|
||||
for (j = 1; last != -1; j++) { /* print the remaining lines in the order list */
|
||||
if (j < mp->lines) /* more lines to process? */
|
||||
i = *iptr++; /* get next line in list */
|
||||
else /* final iteration */
|
||||
@@ -5622,6 +5663,64 @@ if ((dptr) && (dbits & dptr->dctrl)) {
|
||||
|
||||
/* Testing of sim_sock and tmxr */
|
||||
|
||||
static struct lnorder_test {
|
||||
const char *orderspec;
|
||||
int32 valspec;
|
||||
t_stat expected_stat;
|
||||
int32 expected_orderlist[8];
|
||||
} lnorders[] = {
|
||||
{NULL, 0, SCPE_MISVAL},
|
||||
{"", 0, SCPE_MISVAL},
|
||||
{"4-7", 0x3FFF3FFF, SCPE_IERR},
|
||||
{"6-8", 0, SCPE_SUB},
|
||||
{"9-11", 0, SCPE_SUB},
|
||||
{"4-7", 0, SCPE_OK,
|
||||
{ 4, 5, 6, 7, -1}},
|
||||
{"1;5;2-4;7;ALL", 0, SCPE_OK,
|
||||
{ 1, 5, 2, 3, 4, 7, 0, 6}},
|
||||
{"ALL", 0, SCPE_OK,
|
||||
{ -1}},
|
||||
};
|
||||
|
||||
static t_stat _lnorder_test (TMXR *tmxr,
|
||||
struct lnorder_test *t)
|
||||
{
|
||||
t_stat r;
|
||||
char msg[80] = "";
|
||||
int i;
|
||||
|
||||
r = tmxr_set_lnorder (NULL, t->valspec, t->orderspec, tmxr);
|
||||
if (r != t->expected_stat) {
|
||||
snprintf (msg, sizeof (msg), "Unexpected lnorder result status for \"%s\" Expected: %s", t->orderspec, sim_error_text (t->expected_stat));
|
||||
return sim_messagef (SCPE_ARG, "%s, Got: %s\n", msg, sim_error_text (r));
|
||||
}
|
||||
if (r == SCPE_OK) {
|
||||
for (i = 0; i<8; i++)
|
||||
if (t->expected_orderlist[i] != tmxr->lnorder[i])
|
||||
return sim_messagef (SCPE_ARG, "Unexpected order entry for line %d: %d vs %d\n", i, tmxr->lnorder[i], t->expected_orderlist[i]);
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
static t_stat sim_tmxr_test_lnorder (TMXR *tmxr)
|
||||
{
|
||||
int i;
|
||||
int32 *saved_lnorder = tmxr->lnorder;
|
||||
int32 saved_lines = tmxr->lines;
|
||||
|
||||
tmxr->lnorder = calloc (tmxr->lines, sizeof (*tmxr->lnorder));
|
||||
if (tmxr->lines >= 8) {
|
||||
tmxr->lines = 8;
|
||||
for (i = 0; i < (sizeof (lnorders)/sizeof (lnorders[0])); ++i)
|
||||
_lnorder_test (tmxr, &lnorders[i]);
|
||||
}
|
||||
free (tmxr->lnorder);
|
||||
tmxr->lnorder = saved_lnorder;
|
||||
tmxr->lines = saved_lines;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
||||
#include <setjmp.h>
|
||||
|
||||
t_stat tmxr_sock_test (DEVICE *dptr)
|
||||
@@ -5676,6 +5775,7 @@ if (tmxr->lines > 1) {
|
||||
sim_close_sock (sock_line);
|
||||
sock_line = INVALID_SOCKET;
|
||||
SIM_TEST(detach_cmd (0, dptr->name));
|
||||
SIM_TEST(sim_tmxr_test_lnorder (tmxr));
|
||||
}
|
||||
return stat;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user