SCP: Add the ability to Fprintf to memory buffer
This commit is contained in:
parent
5c6dabbccf
commit
8dcc8c0678
2 changed files with 69 additions and 7 deletions
68
scp.c
68
scp.c
|
@ -523,6 +523,7 @@ int32 sim_interval = 0;
|
||||||
int32 sim_switches = 0;
|
int32 sim_switches = 0;
|
||||||
FILE *sim_ofile = NULL;
|
FILE *sim_ofile = NULL;
|
||||||
TMLN *sim_oline = NULL;
|
TMLN *sim_oline = NULL;
|
||||||
|
MEMFILE *sim_mfile = NULL;
|
||||||
SCHTAB *sim_schrptr = FALSE;
|
SCHTAB *sim_schrptr = FALSE;
|
||||||
SCHTAB *sim_schaptr = FALSE;
|
SCHTAB *sim_schaptr = FALSE;
|
||||||
DEVICE *sim_dfdev = NULL;
|
DEVICE *sim_dfdev = NULL;
|
||||||
|
@ -4704,7 +4705,9 @@ t_stat show_queue (FILE *st, DEVICE *dnotused, UNIT *unotused, int32 flag, CONST
|
||||||
DEVICE *dptr;
|
DEVICE *dptr;
|
||||||
UNIT *uptr;
|
UNIT *uptr;
|
||||||
int32 accum;
|
int32 accum;
|
||||||
|
MEMFILE buf;
|
||||||
|
|
||||||
|
memset (&buf, 0, sizeof (buf));
|
||||||
if (cptr && (*cptr != 0))
|
if (cptr && (*cptr != 0))
|
||||||
return SCPE_2MARG;
|
return SCPE_2MARG;
|
||||||
if (sim_clock_queue == QUEUE_LIST_END)
|
if (sim_clock_queue == QUEUE_LIST_END)
|
||||||
|
@ -4745,6 +4748,7 @@ else {
|
||||||
sim_show_clock_queues (st, dnotused, unotused, flag, cptr);
|
sim_show_clock_queues (st, dnotused, unotused, flag, cptr);
|
||||||
#if defined (SIM_ASYNCH_IO)
|
#if defined (SIM_ASYNCH_IO)
|
||||||
pthread_mutex_lock (&sim_asynch_lock);
|
pthread_mutex_lock (&sim_asynch_lock);
|
||||||
|
sim_mfile = &buf;
|
||||||
fprintf (st, "asynchronous pending event queue\n");
|
fprintf (st, "asynchronous pending event queue\n");
|
||||||
if (sim_asynch_queue == QUEUE_LIST_END)
|
if (sim_asynch_queue == QUEUE_LIST_END)
|
||||||
fprintf (st, " Empty\n");
|
fprintf (st, " Empty\n");
|
||||||
|
@ -4762,6 +4766,9 @@ else {
|
||||||
fprintf (st, "asynch latency: %d nanoseconds\n", sim_asynch_latency);
|
fprintf (st, "asynch latency: %d nanoseconds\n", sim_asynch_latency);
|
||||||
fprintf (st, "asynch instruction latency: %d instructions\n", sim_asynch_inst_latency);
|
fprintf (st, "asynch instruction latency: %d instructions\n", sim_asynch_inst_latency);
|
||||||
pthread_mutex_unlock (&sim_asynch_lock);
|
pthread_mutex_unlock (&sim_asynch_lock);
|
||||||
|
sim_mfile = NULL;
|
||||||
|
fprintf (st, "%*.*s", (int)buf.pos, (int)buf.pos, buf.buf);
|
||||||
|
free (buf.buf);
|
||||||
#endif /* SIM_ASYNCH_IO */
|
#endif /* SIM_ASYNCH_IO */
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
@ -10931,12 +10938,61 @@ int Fprintf (FILE *f, const char* fmt, ...)
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
va_list args;
|
va_list args;
|
||||||
|
|
||||||
va_start (args, fmt);
|
if (sim_mfile) {
|
||||||
if (sim_oline)
|
char stackbuf[STACKBUFSIZE];
|
||||||
tmxr_linemsgvf (sim_oline, fmt, args);
|
int32 bufsize = sizeof(stackbuf);
|
||||||
else
|
char *buf = stackbuf;
|
||||||
ret = vfprintf (f, fmt, args);
|
va_list arglist;
|
||||||
va_end (args);
|
int32 len;
|
||||||
|
|
||||||
|
buf[bufsize-1] = '\0';
|
||||||
|
|
||||||
|
while (1) { /* format passed string, args */
|
||||||
|
va_start (arglist, fmt);
|
||||||
|
#if defined(NO_vsnprintf)
|
||||||
|
len = vsprintf (buf, fmt, arglist);
|
||||||
|
#else /* !defined(NO_vsnprintf) */
|
||||||
|
len = vsnprintf (buf, bufsize-1, fmt, arglist);
|
||||||
|
#endif /* NO_vsnprintf */
|
||||||
|
va_end (arglist);
|
||||||
|
|
||||||
|
/* If the formatted result didn't fit into the buffer, then grow the buffer and try again */
|
||||||
|
|
||||||
|
if ((len < 0) || (len >= bufsize-1)) {
|
||||||
|
if (buf != stackbuf)
|
||||||
|
free (buf);
|
||||||
|
bufsize = bufsize * 2;
|
||||||
|
if (bufsize < len + 2)
|
||||||
|
bufsize = len + 2;
|
||||||
|
buf = (char *) malloc (bufsize);
|
||||||
|
if (buf == NULL) /* out of memory */
|
||||||
|
return -1;
|
||||||
|
buf[bufsize-1] = '\0';
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Store the formatted data */
|
||||||
|
|
||||||
|
if (sim_mfile->pos + len > sim_mfile->size) {
|
||||||
|
sim_mfile->size = sim_mfile->pos + 2 * MAX(bufsize, 512);
|
||||||
|
sim_mfile->buf = (char *)realloc (sim_mfile->buf, sim_mfile->size);
|
||||||
|
}
|
||||||
|
memcpy (sim_mfile->buf + sim_mfile->pos, buf, len);
|
||||||
|
sim_mfile->pos += len;
|
||||||
|
|
||||||
|
if (buf != stackbuf)
|
||||||
|
free (buf);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
va_start (args, fmt);
|
||||||
|
if (sim_oline)
|
||||||
|
tmxr_linemsgvf (sim_oline, fmt, args);
|
||||||
|
else
|
||||||
|
ret = vfprintf (f, fmt, args);
|
||||||
|
va_end (args);
|
||||||
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -428,6 +428,7 @@ typedef struct EXPECT EXPECT;
|
||||||
typedef struct SEND SEND;
|
typedef struct SEND SEND;
|
||||||
typedef struct DEBTAB DEBTAB;
|
typedef struct DEBTAB DEBTAB;
|
||||||
typedef struct FILEREF FILEREF;
|
typedef struct FILEREF FILEREF;
|
||||||
|
typedef struct MEMFILE MEMFILE;
|
||||||
typedef struct BITFIELD BITFIELD;
|
typedef struct BITFIELD BITFIELD;
|
||||||
|
|
||||||
typedef t_stat (*ACTIVATE_API)(UNIT *unit, int32 interval);
|
typedef t_stat (*ACTIVATE_API)(UNIT *unit, int32 interval);
|
||||||
|
@ -806,13 +807,18 @@ struct DEBTAB {
|
||||||
#define SIM_DBG_ACTIVATE 0x20000
|
#define SIM_DBG_ACTIVATE 0x20000
|
||||||
#define SIM_DBG_AIO_QUEUE 0x40000
|
#define SIM_DBG_AIO_QUEUE 0x40000
|
||||||
|
|
||||||
/* File Reference */
|
/* Open File Reference */
|
||||||
struct FILEREF {
|
struct FILEREF {
|
||||||
char name[CBUFSIZE]; /* file name */
|
char name[CBUFSIZE]; /* file name */
|
||||||
FILE *file; /* file handle */
|
FILE *file; /* file handle */
|
||||||
int32 refcount; /* reference count */
|
int32 refcount; /* reference count */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct MEMFILE {
|
||||||
|
char *buf; /* buffered data */
|
||||||
|
size_t size; /* size */
|
||||||
|
size_t pos; /* data used */
|
||||||
|
};
|
||||||
/*
|
/*
|
||||||
The following macros exist to help populate structure contents
|
The following macros exist to help populate structure contents
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue