scriptreplay: print info and signals
Signed-off-by: Karel Zak <kzak@redhat.com>
This commit is contained in:
parent
3cecd17610
commit
7c4a374f63
|
@ -76,9 +76,11 @@ enum {
|
|||
};
|
||||
|
||||
struct replay_log {
|
||||
const char *streams; /* 'I'nput, 'O'utput or both */
|
||||
const char *streams; /* 'I'nput, 'O'utput or both */
|
||||
const char *filename;
|
||||
FILE *fp;
|
||||
|
||||
unsigned int noseek; /* do not seek in this log */
|
||||
};
|
||||
|
||||
struct replay_step {
|
||||
|
@ -86,6 +88,9 @@ struct replay_step {
|
|||
double delay;
|
||||
size_t size;
|
||||
|
||||
char *name; /* signals / heders */
|
||||
char *value;
|
||||
|
||||
struct replay_log *data;
|
||||
};
|
||||
|
||||
|
@ -139,6 +144,28 @@ static int replay_set_crmode(struct replay_setup *stp, int mode)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static struct replay_log *replay_new_log(struct replay_setup *stp,
|
||||
const char *streams,
|
||||
const char *filename,
|
||||
FILE *f)
|
||||
{
|
||||
struct replay_log *log;
|
||||
|
||||
assert(stp);
|
||||
assert(streams);
|
||||
assert(filename);
|
||||
|
||||
stp->logs = xrealloc(stp->logs, (stp->nlogs + 1) * sizeof(*log));
|
||||
log = &stp->logs[stp->nlogs];
|
||||
stp->nlogs++;
|
||||
|
||||
log->filename = filename;
|
||||
log->streams = streams;
|
||||
log->fp = f;
|
||||
|
||||
return log;
|
||||
}
|
||||
|
||||
static int replay_set_timing_file(struct replay_setup *stp, const char *filename)
|
||||
{
|
||||
int c, rc = 0;
|
||||
|
@ -170,30 +197,39 @@ static int replay_set_timing_file(struct replay_setup *stp, const char *filename
|
|||
stp->timing_fp = NULL;
|
||||
}
|
||||
|
||||
/* create quasi-log for signals, headers, etc. */
|
||||
if (rc == 0 && stp->timing_format == REPLAY_TIMING_MULTI) {
|
||||
struct replay_log *log = replay_new_log(stp, "SH",
|
||||
filename, stp->timing_fp);
|
||||
if (!log)
|
||||
rc = -ENOMEM;
|
||||
else {
|
||||
log->noseek = 1;
|
||||
DBG(LOG, ul_debug("accociate log file '%s' with 'SH'", filename));
|
||||
}
|
||||
}
|
||||
|
||||
DBG(TIMING, ul_debug("timing file set to '%s' [rc=%d]", filename, rc));
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
static int replay_associate_log(struct replay_setup *stp,
|
||||
const char *streams, const char *filename)
|
||||
{
|
||||
struct replay_log *log;
|
||||
FILE *f;
|
||||
int rc;
|
||||
|
||||
assert(stp);
|
||||
assert(streams);
|
||||
assert(filename);
|
||||
|
||||
stp->logs = xrealloc(stp->logs, (stp->nlogs + 1) * sizeof(*log));
|
||||
log = &stp->logs[stp->nlogs];
|
||||
stp->nlogs++;
|
||||
|
||||
log->filename = filename;
|
||||
log->streams = streams;
|
||||
|
||||
/* open the file and skip the first line */
|
||||
log->fp = fopen(filename, "r");
|
||||
rc = log->fp == NULL ? -errno : ignore_line(log->fp);
|
||||
f = fopen(filename, "r");
|
||||
rc = f == NULL ? -errno : ignore_line(f);
|
||||
|
||||
if (rc == 0)
|
||||
replay_new_log(stp, streams, filename, f);
|
||||
|
||||
DBG(LOG, ul_debug("accociate log file '%s' with '%s' [rc=%d]", filename, streams, rc));
|
||||
return rc;
|
||||
|
@ -208,11 +244,22 @@ static int is_wanted_stream(char type, const char *streams)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void replay_reset_step(struct replay_step *step)
|
||||
{
|
||||
assert(step);
|
||||
|
||||
step->size = 0;
|
||||
step->delay = 0;
|
||||
step->data = NULL;
|
||||
step->type = 0;
|
||||
}
|
||||
|
||||
static int read_multistream_step(struct replay_step *step, FILE *f, char type)
|
||||
{
|
||||
int rc = 0;
|
||||
char nl;
|
||||
|
||||
|
||||
switch (type) {
|
||||
case 'O': /* output */
|
||||
case 'I': /* input */
|
||||
|
@ -224,12 +271,34 @@ static int read_multistream_step(struct replay_step *step, FILE *f, char type)
|
|||
break;
|
||||
|
||||
case 'S': /* signal */
|
||||
rc = ignore_line(f); /* not implemnted yet */
|
||||
break;
|
||||
|
||||
case 'H': /* header */
|
||||
rc = ignore_line(f); /* not implemnted yet */
|
||||
{
|
||||
char buf[BUFSIZ];
|
||||
|
||||
rc = fscanf(f, "%lf ", &step->delay); /* delay */
|
||||
if (rc != 1)
|
||||
break;
|
||||
|
||||
rc = fscanf(f, "%s", buf); /* name */
|
||||
if (rc != 1)
|
||||
break;
|
||||
step->name = strrealloc(step->name, buf);
|
||||
if (!step->name)
|
||||
err_oom();
|
||||
|
||||
if (!fgets(buf, sizeof(buf), f)) { /* value */
|
||||
rc = -errno;
|
||||
break;
|
||||
}
|
||||
if (*buf) {
|
||||
strrem(buf, '\n');
|
||||
step->value = strrealloc(step->value, buf);
|
||||
if (!step->value)
|
||||
err_oom();
|
||||
}
|
||||
rc = 0;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -253,6 +322,9 @@ static struct replay_log *replay_get_stream_log(struct replay_setup *stp, char s
|
|||
|
||||
static int replay_seek_log(struct replay_log *log, size_t move)
|
||||
{
|
||||
if (log->noseek)
|
||||
return 0;
|
||||
|
||||
DBG(LOG, ul_debug(" %s: seek ++ %zu", log->filename, move));
|
||||
return fseek(log->fp, move, SEEK_CUR) == (off_t) -1 ? -errno : 0;
|
||||
}
|
||||
|
@ -284,7 +356,7 @@ static int replay_get_next_step(struct replay_setup *stp, char *streams, struct
|
|||
|
||||
DBG(TIMING, ul_debug("reading next step"));
|
||||
|
||||
memset(step, 0, sizeof(*step));
|
||||
replay_reset_step(step);
|
||||
stp->timing_line++;
|
||||
|
||||
switch (stp->timing_format) {
|
||||
|
@ -348,6 +420,23 @@ static int replay_emit_step_data(struct replay_setup *stp, struct replay_step *s
|
|||
|
||||
assert(stp);
|
||||
assert(step);
|
||||
switch (step->type) {
|
||||
case 'S':
|
||||
assert(step->name);
|
||||
assert(step->value);
|
||||
dprintf(fd, "%s %s\n", step->name, step->value);
|
||||
DBG(LOG, ul_debug("log signal emited"));
|
||||
return 0;
|
||||
case 'H':
|
||||
assert(step->name);
|
||||
assert(step->value);
|
||||
dprintf(fd, "%10s: %s\n", step->name, step->value);
|
||||
DBG(LOG, ul_debug("log signal emited"));
|
||||
return 0;
|
||||
default:
|
||||
break; /* continue with real data */
|
||||
}
|
||||
|
||||
assert(step->size);
|
||||
assert(step->data);
|
||||
assert(step->data->fp);
|
||||
|
@ -428,7 +517,7 @@ usage(void)
|
|||
fputs(USAGE_SEPARATOR, out);
|
||||
fputs(_(" -d, --divisor <num> speed up or slow down execution with time divisor\n"), out);
|
||||
fputs(_(" -m, --maxdelay <num> wait at most this many seconds between updates\n"), out);
|
||||
fputs(_(" -x, --stream <name> stream type (out, in or signal)\n"), out);
|
||||
fputs(_(" -x, --stream <name> stream type (out, in, signal or info)\n"), out);
|
||||
fputs(_(" -c, --cr-mode <type> CR char mode (auto, never, always)\n"), out);
|
||||
printf(USAGE_HELP_OPTIONS(25));
|
||||
|
||||
|
@ -573,6 +662,8 @@ main(int argc, char *argv[])
|
|||
appendchr(streams, sizeof(streams), 'O');
|
||||
else if (strcmp("signal", optarg) == 0)
|
||||
appendchr(streams, sizeof(streams), 'S');
|
||||
else if (strcmp("info", optarg) == 0)
|
||||
appendchr(streams, sizeof(streams), 'H');
|
||||
else
|
||||
errx(EXIT_FAILURE, _("unsupported stream name: '%s'"), optarg);
|
||||
break;
|
||||
|
@ -588,11 +679,7 @@ main(int argc, char *argv[])
|
|||
argv += optind;
|
||||
idx = 0;
|
||||
|
||||
if ((argc < 1 && !(log_out || log_in || log_io)) || argc > 3) {
|
||||
warnx(_("wrong number of arguments"));
|
||||
errtryhelp(EXIT_FAILURE);
|
||||
}
|
||||
if (!log_tm)
|
||||
if (!log_tm && idx < argc)
|
||||
log_tm = argv[idx++];
|
||||
if (!log_out && !log_in && !log_io)
|
||||
log_out = idx < argc ? argv[idx++] : "typescript";
|
||||
|
@ -604,7 +691,10 @@ main(int argc, char *argv[])
|
|||
|
||||
if (!log_tm)
|
||||
errx(EXIT_FAILURE, _("timing file not specified"));
|
||||
else if (replay_set_timing_file(&setup, log_tm) != 0)
|
||||
if (!(log_out || log_in || log_io))
|
||||
errx(EXIT_FAILURE, _("data log file not specified"));
|
||||
|
||||
if (replay_set_timing_file(&setup, log_tm) != 0)
|
||||
err(EXIT_FAILURE, _("cannot open %s"), log_tm);
|
||||
|
||||
if (log_out && replay_associate_log(&setup, "O", log_out) != 0)
|
||||
|
|
Loading…
Reference in New Issue