New format sequence "%nL" to display the most recently written line (#121).

This commit is contained in:
Andrew Wood
2024-12-07 23:12:41 +00:00
parent c3648af57f
commit 619a84949f
14 changed files with 252 additions and 120 deletions
+2 -1
View File
@@ -1,6 +1,7 @@
### UNRELEASED
* *fix:* allow **--format** to include "%nA" more than once, with different "n" valeus (#122)
* *feature:* new **--format** sequence "**%nL**", showing the most recent line written (#121)
* *fix:* allow **--format** to include "%nA" more than once, with different "n" values (#122)
* *fix:* allow **--format** to include "%p" more than once
* *fix:* add _configure_ script fallback for **--remote** check when cross-compiling (#120)
* *fix:* allow **extra-display** to be changed by **--remote** (#123)
+20 -1
View File
@@ -1,4 +1,4 @@
.TH PV 1 2024-12-02 pv-1.9.7 "User Commands"
.TH PV 1 2024-12-07 pv-1.9.7 "User Commands"
.\"
.SH NAME
pv \- monitor the progress of data through a pipe
@@ -515,6 +515,12 @@ the last 16 bytes).
Shows only dots if the transfer is being done with \fBsplice\fR(2), since
splicing to or from pipes does not use the buffer.
.TP
.B %nL
Show the first \fIn\fR bytes of the most recently written line (for example,
\*(lq\fB%40L\fR\*(rq shows the first 40 bytes).
If no \fIn\fR is given, then this expands to fill the available space.
Shows only spaces if the transfer is being done with \fBsplice\fR(2).
.TP
.B %N
Show the name prefix given by \*(lq\fB\-\-name\fR\*(rq.
Padded to 9 characters with spaces, and suffixed with \*(lq:\*(rq.
@@ -629,6 +635,15 @@ pv \-d 1234:3
pv \-d 1234
.EE
.in
.PP
Sending logs to a processing script, showing the most recent line as part of
the progress display:
.PP
.in +4
.EX
pv \-F '%a %p : %L' big.log | processing-script
.EE
.in
.\"
.SH EXIT STATUS
An exit status of 1 indicates a problem with the \*(lq\fB\-\-remote\fR\*(rq
@@ -721,6 +736,10 @@ If the input size cannot be calculated, and the output is a block device,
then \fBpv\fR will read the output device's size, use that as if it had been
passed to \*(lq\fB\-\-size\fR\*(rq, and activate
\*(lq\fB\-\-stop\-at\-size\fR\*(rq.
.PP
The \*(lq\fB%nA\fR\*(rq and \*(lq\fB%nL\fR\*(rq format sequences may not be
effective with small input files, and \*(lq\fB%nL\fR\*(rq may be a few lines
out due to buffering within the pipeline itself.
.\"
.SH REPORTING BUGS
Please report any bugs to \fBpv@ivarch.com\fR.
+16
View File
@@ -466,6 +466,13 @@ contain the following sequences:
**splice**(2), since splicing to or from pipes does not use the
buffer.
**%nL**
: Show the first *n* bytes of the most recently written line (for
example, "**%40L**" shows the first 40 bytes). If no *n* is given,
then this expands to fill the available space. Shows only spaces if
the transfer is being done with **splice**(2).
**%N**
: Show the name prefix given by "**\--name**". Padded to 9 characters
@@ -557,6 +564,11 @@ been given.
pv -d 1234
Sending logs to a processing script, showing the most recent line as
part of the progress display:
pv -F '%a %p : %L' big.log | processing-script
# EXIT STATUS
An exit status of 1 indicates a problem with the "**\--remote**" or
@@ -644,6 +656,10 @@ If the input size cannot be calculated, and the output is a block
device, then **pv** will read the output device\'s size, use that as if
it had been passed to "**\--size**", and activate "**\--stop-at-size**".
The "**%nA**" and "**%nL**" format sequences may not be effective with
small input files, and "**%nL**" may be a few lines out due to buffering
within the pipeline itself.
# REPORTING BUGS
Please report any bugs to **pv@ivarch.com**.
+12 -12
View File
@@ -1,7 +1,7 @@
msgid ""
msgstr ""
"Report-Msgid-Bugs-To: pv@ivarch.com\n"
"POT-Creation-Date: 2024-12-07 20:21+0000\n"
"POT-Creation-Date: 2024-12-07 23:06+0000\n"
"PO-Revision-Date: 2024-10-13 20:43+0000\n"
"Last-Translator: mmatous <mmatous@users.noreply.translate.codeberg.org>\n"
"Language-Team: Czech <https://translate.codeberg.org/projects/pv/pv/cs/>\n"
@@ -403,37 +403,37 @@ msgstr "yzafpnum kMGTPEZY"
msgid "yzafpnum KMGTPEZY"
msgstr "yzafpnum KMGTPEZY"
#: src/pv/display.c:686 src/pv/transfer.c:1011
#: src/pv/display.c:693 src/pv/transfer.c:1064
msgid "buffer allocation failed"
msgstr "selhala alokace vyrovnávací paměti"
#: src/pv/display.c:815
#: src/pv/display.c:822
msgid "b"
msgstr "b"
#: src/pv/display.c:818 src/pv/transfer.c:602
#: src/pv/display.c:825 src/pv/transfer.c:602
msgid "B"
msgstr "B"
#: src/pv/display.c:862 src/pv/display.c:877 src/pv/display.c:1115
#: src/pv/display.c:869 src/pv/display.c:884 src/pv/display.c:1139
#: src/pv/loop.c:549
msgid "b/s"
msgstr "b/s"
#: src/pv/display.c:866 src/pv/display.c:881 src/pv/display.c:1119
#: src/pv/display.c:873 src/pv/display.c:888 src/pv/display.c:1143
msgid "/s"
msgstr "/s"
#: src/pv/display.c:866 src/pv/display.c:881 src/pv/display.c:1119
#: src/pv/display.c:873 src/pv/display.c:888 src/pv/display.c:1143
#: src/pv/loop.c:549
msgid "B/s"
msgstr "B/s"
#: src/pv/display.c:909 src/pv/display.c:913
#: src/pv/display.c:916 src/pv/display.c:920
msgid "ETA"
msgstr "ETA"
#: src/pv/display.c:979
#: src/pv/display.c:986
msgid "FIN"
msgstr "FIN"
@@ -521,15 +521,15 @@ msgstr "selhalo nastavení intervalového časovače"
msgid "failed to clear interval timer"
msgstr "selhalo vynulování intervalového časovače"
#: src/pv/transfer.c:740
#: src/pv/transfer.c:752
msgid "line position buffer allocation failed"
msgstr "selhala alokace vyrovnávací paměti pro pozici v řádcích"
#: src/pv/transfer.c:872
#: src/pv/transfer.c:925
msgid "write failed"
msgstr "zápis selhal"
#: src/pv/transfer.c:1109
#: src/pv/transfer.c:1162
msgid "select call failed"
msgstr "selhalo volání select"
+12 -12
View File
@@ -1,7 +1,7 @@
msgid ""
msgstr ""
"Report-Msgid-Bugs-To: pv@ivarch.com\n"
"POT-Creation-Date: 2024-12-07 20:21+0000\n"
"POT-Creation-Date: 2024-12-07 23:06+0000\n"
"PO-Revision-Date: 2024-10-13 20:43+0000\n"
"Last-Translator: fnetX <otto@codeberg.org>\n"
"Language-Team: German <https://translate.codeberg.org/projects/pv/pv/de/>\n"
@@ -426,37 +426,37 @@ msgstr "yzafpnµm kMGTPEZY"
msgid "yzafpnum KMGTPEZY"
msgstr "yzafpnµm KMGTPEZY"
#: src/pv/display.c:686 src/pv/transfer.c:1011
#: src/pv/display.c:693 src/pv/transfer.c:1064
msgid "buffer allocation failed"
msgstr "Speicherzuweisung für den Puffer fehlgeschlagen"
#: src/pv/display.c:815
#: src/pv/display.c:822
msgid "b"
msgstr "b"
#: src/pv/display.c:818 src/pv/transfer.c:602
#: src/pv/display.c:825 src/pv/transfer.c:602
msgid "B"
msgstr "B"
#: src/pv/display.c:862 src/pv/display.c:877 src/pv/display.c:1115
#: src/pv/display.c:869 src/pv/display.c:884 src/pv/display.c:1139
#: src/pv/loop.c:549
msgid "b/s"
msgstr "b/s"
#: src/pv/display.c:866 src/pv/display.c:881 src/pv/display.c:1119
#: src/pv/display.c:873 src/pv/display.c:888 src/pv/display.c:1143
msgid "/s"
msgstr "/s"
#: src/pv/display.c:866 src/pv/display.c:881 src/pv/display.c:1119
#: src/pv/display.c:873 src/pv/display.c:888 src/pv/display.c:1143
#: src/pv/loop.c:549
msgid "B/s"
msgstr "B/s"
#: src/pv/display.c:909 src/pv/display.c:913
#: src/pv/display.c:916 src/pv/display.c:920
msgid "ETA"
msgstr "ETA"
#: src/pv/display.c:979
#: src/pv/display.c:986
msgid "FIN"
msgstr "Endzeit"
@@ -545,15 +545,15 @@ msgstr "konnte Intervall-Timer nicht setzen"
msgid "failed to clear interval timer"
msgstr "konnte Intervall-Timer nicht löschen"
#: src/pv/transfer.c:740
#: src/pv/transfer.c:752
msgid "line position buffer allocation failed"
msgstr "Zuweisung des Zeilenpuffers fehlgeschlagen"
#: src/pv/transfer.c:872
#: src/pv/transfer.c:925
msgid "write failed"
msgstr "write-Aufruf fehlgeschlagen"
#: src/pv/transfer.c:1109
#: src/pv/transfer.c:1162
msgid "select call failed"
msgstr "select-Aufruf fehlgeschlagen"
+12 -12
View File
@@ -1,7 +1,7 @@
msgid ""
msgstr ""
"Report-Msgid-Bugs-To: pv@ivarch.com\n"
"POT-Creation-Date: 2024-12-07 20:21+0000\n"
"POT-Creation-Date: 2024-12-07 23:06+0000\n"
"Language: es\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -395,37 +395,37 @@ msgstr ""
msgid "yzafpnum KMGTPEZY"
msgstr ""
#: src/pv/display.c:686 src/pv/transfer.c:1011
#: src/pv/display.c:693 src/pv/transfer.c:1064
msgid "buffer allocation failed"
msgstr ""
#: src/pv/display.c:815
#: src/pv/display.c:822
msgid "b"
msgstr ""
#: src/pv/display.c:818 src/pv/transfer.c:602
#: src/pv/display.c:825 src/pv/transfer.c:602
msgid "B"
msgstr ""
#: src/pv/display.c:862 src/pv/display.c:877 src/pv/display.c:1115
#: src/pv/display.c:869 src/pv/display.c:884 src/pv/display.c:1139
#: src/pv/loop.c:549
msgid "b/s"
msgstr ""
#: src/pv/display.c:866 src/pv/display.c:881 src/pv/display.c:1119
#: src/pv/display.c:873 src/pv/display.c:888 src/pv/display.c:1143
msgid "/s"
msgstr ""
#: src/pv/display.c:866 src/pv/display.c:881 src/pv/display.c:1119
#: src/pv/display.c:873 src/pv/display.c:888 src/pv/display.c:1143
#: src/pv/loop.c:549
msgid "B/s"
msgstr ""
#: src/pv/display.c:909 src/pv/display.c:913
#: src/pv/display.c:916 src/pv/display.c:920
msgid "ETA"
msgstr ""
#: src/pv/display.c:979
#: src/pv/display.c:986
msgid "FIN"
msgstr ""
@@ -513,15 +513,15 @@ msgstr ""
msgid "failed to clear interval timer"
msgstr ""
#: src/pv/transfer.c:740
#: src/pv/transfer.c:752
msgid "line position buffer allocation failed"
msgstr ""
#: src/pv/transfer.c:872
#: src/pv/transfer.c:925
msgid "write failed"
msgstr ""
#: src/pv/transfer.c:1109
#: src/pv/transfer.c:1162
msgid "select call failed"
msgstr ""
+12 -12
View File
@@ -1,7 +1,7 @@
msgid ""
msgstr ""
"Report-Msgid-Bugs-To: pv@ivarch.com\n"
"POT-Creation-Date: 2024-12-07 20:21+0000\n"
"POT-Creation-Date: 2024-12-07 23:06+0000\n"
"PO-Revision-Date: 2024-10-12 11:13+0000\n"
"Last-Translator: a-j-wood <a-j-wood@users.noreply.translate.codeberg.org>\n"
"Language-Team: French <https://translate.codeberg.org/projects/pv/pv/fr/>\n"
@@ -430,37 +430,37 @@ msgstr ""
msgid "yzafpnum KMGTPEZY"
msgstr ""
#: src/pv/display.c:686 src/pv/transfer.c:1011
#: src/pv/display.c:693 src/pv/transfer.c:1064
msgid "buffer allocation failed"
msgstr "échec de l'allocation de mémoire tampon"
#: src/pv/display.c:815
#: src/pv/display.c:822
msgid "b"
msgstr ""
#: src/pv/display.c:818 src/pv/transfer.c:602
#: src/pv/display.c:825 src/pv/transfer.c:602
msgid "B"
msgstr "O"
#: src/pv/display.c:862 src/pv/display.c:877 src/pv/display.c:1115
#: src/pv/display.c:869 src/pv/display.c:884 src/pv/display.c:1139
#: src/pv/loop.c:549
msgid "b/s"
msgstr ""
#: src/pv/display.c:866 src/pv/display.c:881 src/pv/display.c:1119
#: src/pv/display.c:873 src/pv/display.c:888 src/pv/display.c:1143
msgid "/s"
msgstr "/s"
#: src/pv/display.c:866 src/pv/display.c:881 src/pv/display.c:1119
#: src/pv/display.c:873 src/pv/display.c:888 src/pv/display.c:1143
#: src/pv/loop.c:549
msgid "B/s"
msgstr "O/s"
#: src/pv/display.c:909 src/pv/display.c:913
#: src/pv/display.c:916 src/pv/display.c:920
msgid "ETA"
msgstr "ETA"
#: src/pv/display.c:979
#: src/pv/display.c:986
msgid "FIN"
msgstr ""
@@ -548,15 +548,15 @@ msgstr ""
msgid "failed to clear interval timer"
msgstr ""
#: src/pv/transfer.c:740
#: src/pv/transfer.c:752
msgid "line position buffer allocation failed"
msgstr ""
#: src/pv/transfer.c:872
#: src/pv/transfer.c:925
msgid "write failed"
msgstr "l'écriture a échoué"
#: src/pv/transfer.c:1109
#: src/pv/transfer.c:1162
msgid "select call failed"
msgstr "l'appel de sélection a échoué"
+12 -12
View File
@@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: pv@ivarch.com\n"
"POT-Creation-Date: 2024-12-07 20:21+0000\n"
"POT-Creation-Date: 2024-12-07 23:06+0000\n"
"PO-Revision-Date: 2024-10-20 14:07+0000\n"
"Last-Translator: coralpink <coralpink@users.noreply.translate.codeberg.org>\n"
"Language-Team: Polish <https://translate.codeberg.org/projects/pv/pv/pl/>\n"
@@ -421,37 +421,37 @@ msgstr "yzafpnum kMGTPEZY"
msgid "yzafpnum KMGTPEZY"
msgstr "yzafpnum KMGTPEZY"
#: src/pv/display.c:686 src/pv/transfer.c:1011
#: src/pv/display.c:693 src/pv/transfer.c:1064
msgid "buffer allocation failed"
msgstr "nie udało się zaalokować bufora"
#: src/pv/display.c:815
#: src/pv/display.c:822
msgid "b"
msgstr "b"
#: src/pv/display.c:818 src/pv/transfer.c:602
#: src/pv/display.c:825 src/pv/transfer.c:602
msgid "B"
msgstr "B"
#: src/pv/display.c:862 src/pv/display.c:877 src/pv/display.c:1115
#: src/pv/display.c:869 src/pv/display.c:884 src/pv/display.c:1139
#: src/pv/loop.c:549
msgid "b/s"
msgstr "b/s"
#: src/pv/display.c:866 src/pv/display.c:881 src/pv/display.c:1119
#: src/pv/display.c:873 src/pv/display.c:888 src/pv/display.c:1143
msgid "/s"
msgstr "/s"
#: src/pv/display.c:866 src/pv/display.c:881 src/pv/display.c:1119
#: src/pv/display.c:873 src/pv/display.c:888 src/pv/display.c:1143
#: src/pv/loop.c:549
msgid "B/s"
msgstr "B/s"
#: src/pv/display.c:909 src/pv/display.c:913
#: src/pv/display.c:916 src/pv/display.c:920
msgid "ETA"
msgstr "ETA"
#: src/pv/display.c:979
#: src/pv/display.c:986
msgid "FIN"
msgstr "FIN"
@@ -541,15 +541,15 @@ msgstr "nie udało się ustawić interwału czasowego"
msgid "failed to clear interval timer"
msgstr "nie udało się wyczyścić interwału czasowego"
#: src/pv/transfer.c:740
#: src/pv/transfer.c:752
msgid "line position buffer allocation failed"
msgstr "alokacja buforu pozycji linii nie powiodła się"
#: src/pv/transfer.c:872
#: src/pv/transfer.c:925
msgid "write failed"
msgstr "błąd zapisu"
#: src/pv/transfer.c:1109
#: src/pv/transfer.c:1162
msgid "select call failed"
msgstr "nie udało się wywołać funkcji select"
+12 -12
View File
@@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: pv@ivarch.com\n"
"POT-Creation-Date: 2024-12-07 20:21+0000\n"
"POT-Creation-Date: 2024-12-07 23:06+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -409,37 +409,37 @@ msgstr ""
msgid "yzafpnum KMGTPEZY"
msgstr ""
#: src/pv/display.c:686 src/pv/transfer.c:1011
#: src/pv/display.c:693 src/pv/transfer.c:1064
msgid "buffer allocation failed"
msgstr "erro alocando o buffer"
#: src/pv/display.c:815
#: src/pv/display.c:822
msgid "b"
msgstr ""
#: src/pv/display.c:818 src/pv/transfer.c:602
#: src/pv/display.c:825 src/pv/transfer.c:602
msgid "B"
msgstr ""
#: src/pv/display.c:862 src/pv/display.c:877 src/pv/display.c:1115
#: src/pv/display.c:869 src/pv/display.c:884 src/pv/display.c:1139
#: src/pv/loop.c:549
msgid "b/s"
msgstr ""
#: src/pv/display.c:866 src/pv/display.c:881 src/pv/display.c:1119
#: src/pv/display.c:873 src/pv/display.c:888 src/pv/display.c:1143
msgid "/s"
msgstr ""
#: src/pv/display.c:866 src/pv/display.c:881 src/pv/display.c:1119
#: src/pv/display.c:873 src/pv/display.c:888 src/pv/display.c:1143
#: src/pv/loop.c:549
msgid "B/s"
msgstr "B/s"
#: src/pv/display.c:909 src/pv/display.c:913
#: src/pv/display.c:916 src/pv/display.c:920
msgid "ETA"
msgstr "ETA"
#: src/pv/display.c:979
#: src/pv/display.c:986
msgid "FIN"
msgstr ""
@@ -527,15 +527,15 @@ msgstr ""
msgid "failed to clear interval timer"
msgstr ""
#: src/pv/transfer.c:740
#: src/pv/transfer.c:752
msgid "line position buffer allocation failed"
msgstr ""
#: src/pv/transfer.c:872
#: src/pv/transfer.c:925
msgid "write failed"
msgstr "erro de gravação"
#: src/pv/transfer.c:1109
#: src/pv/transfer.c:1162
msgid "select call failed"
msgstr "erro na chamada da função select"
+12 -12
View File
@@ -1,7 +1,7 @@
msgid ""
msgstr ""
"Report-Msgid-Bugs-To: pv@ivarch.com\n"
"POT-Creation-Date: 2024-12-07 20:21+0000\n"
"POT-Creation-Date: 2024-12-07 23:06+0000\n"
"PO-Revision-Date: 2024-10-22 18:07+0000\n"
"Last-Translator: 0ko <0ko@users.noreply.translate.codeberg.org>\n"
"Language-Team: Russian <https://translate.codeberg.org/projects/pv/pv/ru/>\n"
@@ -404,37 +404,37 @@ msgstr ""
msgid "yzafpnum KMGTPEZY"
msgstr ""
#: src/pv/display.c:686 src/pv/transfer.c:1011
#: src/pv/display.c:693 src/pv/transfer.c:1064
msgid "buffer allocation failed"
msgstr "не удалось выделить память для буфера"
#: src/pv/display.c:815
#: src/pv/display.c:822
msgid "b"
msgstr "бит"
#: src/pv/display.c:818 src/pv/transfer.c:602
#: src/pv/display.c:825 src/pv/transfer.c:602
msgid "B"
msgstr "байт"
#: src/pv/display.c:862 src/pv/display.c:877 src/pv/display.c:1115
#: src/pv/display.c:869 src/pv/display.c:884 src/pv/display.c:1139
#: src/pv/loop.c:549
msgid "b/s"
msgstr "бит/с"
#: src/pv/display.c:866 src/pv/display.c:881 src/pv/display.c:1119
#: src/pv/display.c:873 src/pv/display.c:888 src/pv/display.c:1143
msgid "/s"
msgstr "/с"
#: src/pv/display.c:866 src/pv/display.c:881 src/pv/display.c:1119
#: src/pv/display.c:873 src/pv/display.c:888 src/pv/display.c:1143
#: src/pv/loop.c:549
msgid "B/s"
msgstr "байт/с"
#: src/pv/display.c:909 src/pv/display.c:913
#: src/pv/display.c:916 src/pv/display.c:920
msgid "ETA"
msgstr "ОЖИД"
#: src/pv/display.c:979
#: src/pv/display.c:986
msgid "FIN"
msgstr "ЗАВЕРШ"
@@ -522,15 +522,15 @@ msgstr "не удалось задать измеритель временног
msgid "failed to clear interval timer"
msgstr "не удалось очистить измеритель временного промежутка"
#: src/pv/transfer.c:740
#: src/pv/transfer.c:752
msgid "line position buffer allocation failed"
msgstr ""
#: src/pv/transfer.c:872
#: src/pv/transfer.c:925
msgid "write failed"
msgstr "запись не удалась"
#: src/pv/transfer.c:1109
#: src/pv/transfer.c:1162
msgid "select call failed"
msgstr "запрос выборки не удался"
+12 -12
View File
@@ -2,7 +2,7 @@ msgid ""
msgstr ""
"Project-Id-Version: pv 1.8.14\n"
"Report-Msgid-Bugs-To: pv@ivarch.com\n"
"POT-Creation-Date: 2024-12-07 20:21+0000\n"
"POT-Creation-Date: 2024-12-07 23:06+0000\n"
"PO-Revision-Date: 2024-10-12 23:51+0000\n"
"Last-Translator: a-j-wood <a-j-wood@users.noreply.translate.codeberg.org>\n"
"Language-Team: Turkish <https://translate.codeberg.org/projects/pv/pv/tr/>\n"
@@ -405,37 +405,37 @@ msgstr "yzafpnum kMGTPEZY"
msgid "yzafpnum KMGTPEZY"
msgstr "yzafpnum KMGTPEZY"
#: src/pv/display.c:686 src/pv/transfer.c:1011
#: src/pv/display.c:693 src/pv/transfer.c:1064
msgid "buffer allocation failed"
msgstr "arabellek tahsisi başarısız oldu"
#: src/pv/display.c:815
#: src/pv/display.c:822
msgid "b"
msgstr "b"
#: src/pv/display.c:818 src/pv/transfer.c:602
#: src/pv/display.c:825 src/pv/transfer.c:602
msgid "B"
msgstr "B"
#: src/pv/display.c:862 src/pv/display.c:877 src/pv/display.c:1115
#: src/pv/display.c:869 src/pv/display.c:884 src/pv/display.c:1139
#: src/pv/loop.c:549
msgid "b/s"
msgstr "b/s"
#: src/pv/display.c:866 src/pv/display.c:881 src/pv/display.c:1119
#: src/pv/display.c:873 src/pv/display.c:888 src/pv/display.c:1143
msgid "/s"
msgstr "/s"
#: src/pv/display.c:866 src/pv/display.c:881 src/pv/display.c:1119
#: src/pv/display.c:873 src/pv/display.c:888 src/pv/display.c:1143
#: src/pv/loop.c:549
msgid "B/s"
msgstr "B/s"
#: src/pv/display.c:909 src/pv/display.c:913
#: src/pv/display.c:916 src/pv/display.c:920
msgid "ETA"
msgstr "ETA"
#: src/pv/display.c:979
#: src/pv/display.c:986
msgid "FIN"
msgstr "FIN"
@@ -523,15 +523,15 @@ msgstr "aralık zamanlayıcısı ayarlanamadı"
msgid "failed to clear interval timer"
msgstr "aralık zamanlayıcısı temizlenemedi"
#: src/pv/transfer.c:740
#: src/pv/transfer.c:752
msgid "line position buffer allocation failed"
msgstr "satır konumu arabellek tahsisi başarısız oldu"
#: src/pv/transfer.c:872
#: src/pv/transfer.c:925
msgid "write failed"
msgstr "yazma başarısız"
#: src/pv/transfer.c:1109
#: src/pv/transfer.c:1162
msgid "select call failed"
msgstr "seçme çağrısı başarısız oldu"
+10 -1
View File
@@ -35,6 +35,7 @@ typedef enum {
PV_COMPONENT_NAME, /* name prefix */
PV_COMPONENT_BUFPERCENT, /* percentage of buffer used */
PV_COMPONENT_OUTPUTBUF, /* recent bytes in output buffer */
PV_COMPONENT_PREVLINE, /* most recent complete line */
PV_COMPONENT__MAX
} pv_display_component;
@@ -56,6 +57,7 @@ typedef enum {
#define PV_SIZEOF_DEFAULT_FORMAT 512
#define PV_SIZEOF_CWD 4096
#define PV_SIZEOF_LASTOUTPUT_BUFFER 256
#define PV_SIZEOF_PREVLINE_BUFFER 1024
#define PV_FORMAT_ARRAY_MAX 100
#define PV_SIZEOF_CRS_LOCK_FILE 1024
@@ -202,13 +204,20 @@ struct pvstate_s {
bool required; /* true if included in format */
} component[PV_COMPONENT__MAX];
/* The last-output "n" bytes. */
char lastoutput_buffer[PV_SIZEOF_LASTOUTPUT_BUFFER];
/* The most recently output complete line. */
char previous_line[PV_SIZEOF_PREVLINE_BUFFER];
/* The line being received now. */
char next_line[PV_SIZEOF_PREVLINE_BUFFER];
/*@only@*/ /*@null@*/ char *display_buffer; /* buffer for display string */
size_t display_buffer_size; /* size allocated to display buffer */
size_t display_string_len; /* length of string in display buffer */
off_t initial_offset; /* offset when first opened (when watching fds) */
size_t lastoutput_bytes; /* largest number of last-output bytes to show */
size_t next_line_len; /* length of currently receiving line so far */
size_t format_segment_count; /* number of format string segments */
@@ -307,7 +316,7 @@ struct pvstate_s {
off_t transferred; /* amount transferred (written - unconsumed) */
/* Keep track of line positions to backtrack written_but_not_consumed. */
/*@null@*/ off_t *line_positions; /* line separator write positions (circular buffer) */
/*@only@*/ /*@null@*/ off_t *line_positions; /* line separator write positions (circular buffer) */
size_t line_positions_capacity; /* total size of line position array */
size_t line_positions_length; /* number of positions stored in array */
size_t line_positions_head; /* index to use for next position */
+49 -15
View File
@@ -491,7 +491,8 @@ static void pv__format_init(pvstate_t state, /*@null@ */ const char *format_supp
/*
* Check for a numeric prefix between the % and the
* format character - currently only used with "%A".
* format character - currently only used with "%A"
* and "%L".
*/
#if HAVE_STRTOUL
number_end_ptr = NULL;
@@ -535,6 +536,12 @@ static void pv__format_init(pvstate_t state, /*@null@ */ const char *format_supp
if (display->lastoutput_bytes < chosen_size)
display->lastoutput_bytes = chosen_size;
break;
case 'L':
seg_type = PV_COMPONENT_PREVLINE;
if (number_prefix > PV_SIZEOF_PREVLINE_BUFFER)
number_prefix = PV_SIZEOF_PREVLINE_BUFFER;
chosen_size = (size_t) number_prefix;
break;
case 'r':
seg_type = PV_COMPONENT_RATE;
break;
@@ -631,7 +638,7 @@ bool pv_format(pvstate_t state, /*@null@ */ const char *format_supplied, pvdispl
bool final)
{
long eta;
int static_portion_size, dynamic_segment_count;
int static_portion_size, dynamic_segment_count, dynamic_segment_width;
pv_display_component component_type;
size_t segment;
size_t new_display_string_len;
@@ -1028,6 +1035,18 @@ bool pv_format(pvstate_t state, /*@null@ */ const char *format_supplied, pvdispl
component_content[buf_idx] = '\0';
break;
case PV_COMPONENT_PREVLINE:
/* Most recent line. */
for (buf_idx = 0;
buf_idx < PV_SIZEOF_PREVLINE_BUFFER - 1 && buf_idx < PV_SIZEOF_COMPONENT_STR - 1;
buf_idx++) {
int display_char;
display_char = (int) (display->previous_line[buf_idx]);
component_content[buf_idx] = isprint(display_char) ? (char) display_char : ' ';
}
component_content[buf_idx] = '\0';
break;
default:
break;
}
@@ -1054,6 +1073,10 @@ bool pv_format(pvstate_t state, /*@null@ */ const char *format_supplied, pvdispl
} else if (display->format[segment].type == PV_COMPONENT_PROGRESS) {
dynamic_segment_count++;
debug("segment[%d] type:%d dynamic", segment, display->format[segment].type);
} else if (display->format[segment].type == PV_COMPONENT_PREVLINE
&& 0 == display->format[segment].chosen_size) {
dynamic_segment_count++;
debug("segment[%d] type:%d dynamic", segment, display->format[segment].type);
} else {
size_t segment_width = display->format[segment].chosen_size;
if (0 == segment_width)
@@ -1066,6 +1089,14 @@ bool pv_format(pvstate_t state, /*@null@ */ const char *format_supplied, pvdispl
debug("static_portion_size: %d", static_portion_size);
debug("dynamic_segment_count: %d", dynamic_segment_count);
dynamic_segment_width = (int) (state->control.width) - static_portion_size;
/*
* Divide the total remaining screen space by the number of dynamic
* segments, so that multiple dynamic segments will share the space.
*/
if (dynamic_segment_count > 1)
dynamic_segment_width /= dynamic_segment_count;
/*
* Assemble the progress bar now we know how big it should be.
*/
@@ -1073,7 +1104,7 @@ bool pv_format(pvstate_t state, /*@null@ */ const char *format_supplied, pvdispl
char *component_content;
size_t component_buf_size;
char after_bar[32]; /* flawfinder: ignore - only populated by pv_snprintf(). */
int component_width, bar_area_width, filled_bar_width, pad_count;
int bar_area_width, filled_bar_width, pad_count;
component_content = display->component[PV_COMPONENT_PROGRESS].content;
component_content[0] = '\0';
@@ -1081,13 +1112,6 @@ bool pv_format(pvstate_t state, /*@null@ */ const char *format_supplied, pvdispl
memset(after_bar, 0, sizeof(after_bar));
component_width = (int) (state->control.width) - static_portion_size;
/*
* Divide the total remaining screen space by the number of dynamic segments.
*/
if (dynamic_segment_count > 1)
component_width /= dynamic_segment_count;
if (state->control.size > 0 || state->control.rate_gauge) {
/*
* Known size, or rate gauge mode. Show a bar, and
@@ -1125,7 +1149,7 @@ bool pv_format(pvstate_t state, /*@null@ */ const char *format_supplied, pvdispl
after_bar_width = strlen(after_bar); /* flawfinder: ignore */
/* flawfinder: always \0-terminated by pv_snprintf() and the earlier memset(). */
bar_area_width = component_width - (int) (after_bar_width) - 2;
bar_area_width = dynamic_segment_width - (int) (after_bar_width) - 2;
if (bar_area_width < 0)
bar_area_width = 0;
@@ -1163,7 +1187,7 @@ bool pv_format(pvstate_t state, /*@null@ */ const char *format_supplied, pvdispl
int indicator_position = state->calc.percentage;
bar_area_width = component_width - 5;
bar_area_width = dynamic_segment_width - 5;
if (bar_area_width < 0)
bar_area_width = 0;
@@ -1237,16 +1261,26 @@ bool pv_format(pvstate_t state, /*@null@ */ const char *format_supplied, pvdispl
segment_content = display->component[display->format[segment].type].content;
segment_bytes = display->component[display->format[segment].type].bytes;
/* A chosen_size of 0 for PV_COMPONENT_PREVLINE means dynamic. */
if (0 == chosen_size && PV_COMPONENT_PREVLINE == display->format[segment].type)
chosen_size = (size_t) dynamic_segment_width;
/*
* If the segment's chosen size is smaller than the
* component, show only the last part of it. For
* component, show only the first or last part of
* it, depending on the component type. For
* instance with "show N last output bytes" (%nA),
* if one "n" was 16 and the other 8, then for the 8
* one, we show the last 8 bytes of the 16-byte
* buffer (issue #122).
* buffer (issue #122). With "show previous line",
* we show the first bytes.
*/
if (0 != chosen_size && chosen_size < segment_bytes) {
segment_content += (segment_bytes - chosen_size);
if (PV_COMPONENT_PREVLINE == display->format[segment].type) {
/* No need to move the segment content. */
} else {
segment_content += (segment_bytes - chosen_size);
}
segment_bytes = chosen_size;
}
}
+59 -6
View File
@@ -718,28 +718,42 @@ static int pv__transfer_write(pvstate_t state, bool *eof_in, bool *eof_out, long
}
if (nwritten > 0) {
bool tracking_lines = false;
if ((state->control.linemode) && (lineswritten != NULL))
tracking_lines = true;
else if (state->display.component[PV_COMPONENT_PREVLINE].required)
tracking_lines = true;
/*
* Write returned >0 - data successfully written.
*/
if ((state->control.linemode) && (lineswritten != NULL)) {
if (tracking_lines) {
char separator;
char *ptr;
long lines = 0;
/*
* Line mode - look through what we've just written
* to count how many lines there were.
* Tracking lines - either line mode, or we're
* showing the last line in the display, or both.
* So we need to look through what we've just
* written to either count how many lines there
* were, or get the content of the most recent
* complete line, or both.
*/
/* Allocate buffer to remember line positions. */
if (NULL == state->transfer.line_positions) {
if (NULL == state->transfer.line_positions && NULL != lineswritten) {
state->transfer.line_positions_capacity = MAX_LINE_POSITIONS;
/*@-mustfreeonly@ */
state->transfer.line_positions =
calloc((size_t) (state->transfer.line_positions_capacity), sizeof(off_t));
if (NULL == state->transfer.line_positions) {
pv_error(state, "%s: %s", _("line position buffer allocation failed"),
strerror(errno));
}
/*@+mustfreeonly@ */
/* splint doesn't see we only call calloc() when line_positions is NULL. */
}
if (state->control.null_terminated_lines) {
@@ -752,12 +766,50 @@ static int pv__transfer_write(pvstate_t state, bool *eof_in, bool *eof_out, long
for (ptr++;
ptr - (char *) state->transfer.transfer_buffer - state->transfer.write_position <
(size_t) nwritten; ptr++, state->transfer.last_output_position++) {
if (*ptr != separator)
if (*ptr != separator) {
/*
* If we're displaying the previous
* line ("%L"), add to our line
* buffer.
*/
if (state->display.component[PV_COMPONENT_PREVLINE].required
&& state->display.next_line_len < PV_SIZEOF_PREVLINE_BUFFER - 1) {
state->display.next_line[state->display.next_line_len] = *ptr;
state->display.next_line_len++;
}
continue;
}
/* Separator found - increment line count. */
++lines;
/*
* If we're displaying the previous line
* ("%L"), update the previous-line buffer
* with the line we just completed, and
* start a new one.
*/
if (state->display.component[PV_COMPONENT_PREVLINE].required) {
memset(state->display.previous_line, 0, PV_SIZEOF_PREVLINE_BUFFER);
if (state->display.next_line_len > PV_SIZEOF_PREVLINE_BUFFER - 1)
state->display.next_line_len = PV_SIZEOF_PREVLINE_BUFFER - 1;
if (state->display.next_line_len > 0) {
memcpy(state->display.previous_line, state->display.next_line, /* flawfinder: ignore */
state->display.next_line_len);
debug("%s: [%s]", "updated previous_line",
state->display.previous_line);
}
state->display.next_line_len = 0;
/*
* flawfinder - next_line_len is
* guaranteed to be less than the
* size of the previous_line buffer
* since we check it just before
* memcpy(), and we ensure that the
* last byte in the buffer is \0.
*/
}
if (NULL == state->transfer.line_positions)
continue;
@@ -777,7 +829,8 @@ static int pv__transfer_write(pvstate_t state, bool *eof_in, bool *eof_out, long
}
}
*lineswritten += lines;
if (NULL != lineswritten)
*lineswritten += lines;
}
state->transfer.write_position += nwritten;