]> git.ipfire.org Git - thirdparty/util-linux.git/blobdiff - term-utils/scriptreplay.c
setterm: update comments about -ulcolor/-hbcolor syntax
[thirdparty/util-linux.git] / term-utils / scriptreplay.c
index 9aa4783c05defc09192fb277abc2ba29b81f176c..7b59b6e244b425d787c57b71f655bf9a53a2cb9f 100644 (file)
 
 #include "closestream.h"
 #include "nls.h"
+#include "strutils.h"
 #include "c.h"
 
 #define SCRIPT_MIN_DELAY 0.0001                /* from original sripreplay.pl */
 
-void __attribute__((__noreturn__))
-usage(FILE *out)
+static void __attribute__((__noreturn__))
+usage(void)
 {
-       fputs(_("\nUsage:\n"), out);
+       FILE *out = stdout;
+       fputs(USAGE_HEADER, out);
        fprintf(out,
              _(" %s [-t] timingfile [typescript] [divisor]\n"),
              program_invocation_short_name);
 
-       fputs(_("\nOptions:\n"), out);
+       fputs(USAGE_SEPARATOR, out);
+       fputs(_("Play back terminal typescripts, using timing information.\n"), out);
+
+       fputs(USAGE_OPTIONS, out);
        fputs(_(" -t, --timing <file>     script timing output file\n"
                " -s, --typescript <file> script terminal session output file\n"
                " -d, --divisor <num>     speed up or slow down execution with time divisor\n"
-               " -V, --version           output version information and exit\n"
-               " -h, --help              display this help and exit\n\n"), out);
+               " -m, --maxdelay <num>    wait at most this many seconds between updates\n"
+               ), out);
+       printf(USAGE_HELP_OPTIONS(25));
 
-       exit(out == stderr ? EXIT_FAILURE : EXIT_SUCCESS);
+       printf(USAGE_MAN_TAIL("scriptreplay(1)"));
+       exit(EXIT_SUCCESS);
 }
 
 static double
 getnum(const char *s)
 {
-       double d;
-       char *end;
-
-       errno = 0;
-       d = strtod(s, &end);
-
-       if (end && *end != '\0')
-               errx(EXIT_FAILURE, _("expected a number, but got '%s'"), s);
+       const double d = strtod_or_err(s, _("failed to parse number"));
 
-       if ((d == HUGE_VAL || d == -HUGE_VAL) && ERANGE == errno)
-               err(EXIT_FAILURE, _("divisor '%s'"), s);
-
-       if (!(d==d)) { /* did they specify "nan"? */
+       if (isnan(d)) {
                errno = EINVAL;
-               err(EXIT_FAILURE, _("divisor '%s'"), s);
+               err(EXIT_FAILURE, "%s: %s", _("failed to parse number"), s);
        }
        return d;
 }
@@ -130,16 +127,16 @@ main(int argc, char *argv[])
 {
        FILE *tfile, *sfile;
        const char *sname = NULL, *tname = NULL;
-       double divi = 1;
-       int c, diviopt = FALSE, idx;
+       double divi = 1, maxdelay = 0;
+       int c, diviopt = FALSE, maxdelayopt = FALSE, idx;
        unsigned long line;
-       size_t oldblk = 0;
-       char ch;
+       int ch;
 
        static const struct option longopts[] = {
                { "timing",     required_argument,      0, 't' },
                { "typescript", required_argument,      0, 's' },
                { "divisor",    required_argument,      0, 'd' },
+               { "maxdelay",   required_argument,      0, 'm' },
                { "version",    no_argument,            0, 'V' },
                { "help",       no_argument,            0, 'h' },
                { NULL,         0, 0, 0 }
@@ -156,7 +153,7 @@ main(int argc, char *argv[])
        textdomain(PACKAGE);
        atexit(close_stdout);
 
-       while ((ch = getopt_long(argc, argv, "t:s:d:Vh", longopts, NULL)) != -1)
+       while ((ch = getopt_long(argc, argv, "t:s:d:m:Vh", longopts, NULL)) != -1)
                switch(ch) {
                case 't':
                        tname = optarg;
@@ -168,14 +165,17 @@ main(int argc, char *argv[])
                        diviopt = TRUE;
                        divi = getnum(optarg);
                        break;
+               case 'm':
+                       maxdelayopt = TRUE;
+                       maxdelay = getnum(optarg);
+                       break;
                case 'V':
-                       printf(_("%s from %s\n"), program_invocation_short_name,
-                                                 PACKAGE_STRING);
+                       printf(UTIL_LINUX_VERSION);
                        exit(EXIT_SUCCESS);
                case 'h':
-                       usage(stdout);
+                       usage();
                default:
-                       usage(stderr);
+                       errtryhelp(EXIT_FAILURE);
                        }
        argc -= optind;
        argv += optind;
@@ -183,7 +183,7 @@ main(int argc, char *argv[])
 
        if ((argc < 1 && !tname) || argc > 3) {
                warnx(_("wrong number of arguments"));
-               usage(stderr);
+               errtryhelp(EXIT_FAILURE);
        }
        if (!tname)
                tname = argv[idx++];
@@ -191,7 +191,8 @@ main(int argc, char *argv[])
                sname = idx < argc ? argv[idx++] : "typescript";
        if (!diviopt)
                divi = idx < argc ? getnum(argv[idx]) : 1;
-
+       if (maxdelay < 0)
+               maxdelay = 0;
        tfile = fopen(tname, "r");
        if (!tfile)
                err(EXIT_FAILURE, _("cannot open %s"), tname);
@@ -202,7 +203,7 @@ main(int argc, char *argv[])
        /* ignore the first typescript line */
        while((c = fgetc(sfile)) != EOF && c != '\n');
 
-       for(line = 0; ; line++) {
+       for(line = 1; ; line++) {
                double delay;
                size_t blk;
                char nl;
@@ -214,17 +215,18 @@ main(int argc, char *argv[])
                                err(EXIT_FAILURE,
                                        _("failed to read timing file %s"), tname);
                        errx(EXIT_FAILURE,
-                               _("timings file %s: %lu: unexpected format"),
+                               _("timing file %s: line %lu: unexpected format"),
                                tname, line);
                }
                delay /= divi;
 
+               if (maxdelayopt && delay > maxdelay)
+                       delay = maxdelay;
+
                if (delay > SCRIPT_MIN_DELAY)
                        delay_for(delay);
 
-               if (oldblk)
-                       emit(sfile, sname, oldblk);
-               oldblk = blk;
+               emit(sfile, sname, blk);
        }
 
        fclose(sfile);