1.\" Copyright (c) 2013-2018 Devin Teske 2.\" All rights reserved. 3.\" 4.\" Redistribution and use in source and binary forms, with or without 5.\" modification, are permitted provided that the following conditions 6.\" are met: 7.\" 1. Redistributions of source code must retain the above copyright 8.\" notice, this list of conditions and the following disclaimer. 9.\" 2. Redistributions in binary form must reproduce the above copyright 10.\" notice, this list of conditions and the following disclaimer in the 11.\" documentation and/or other materials provided with the distribution. 12.\" 13.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 14.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 17.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23.\" SUCH DAMAGE. 24.\" 25.\" $FreeBSD$ 26.\" 27.Dd March 13, 2018 28.Dt DPV 3 29.Os 30.Sh NAME 31.Nm dpv 32.Nd dialog progress view library 33.Sh LIBRARY 34.Lb libdpv 35.Sh SYNOPSIS 36.In dpv.h 37.Ft int 38.Fo dpv 39.Fa "struct dpv_config *config" 40.Fa "struct dpv_file_node *file_list" 41.Fc 42.Ft void 43.Fo dpv_free 44.Fa "void" 45.Fc 46.Sh DESCRIPTION 47The 48.Nm 49library provides an interface for creating complex 50.Dq gauge 51widgets for displaying progress on various actions. 52The 53.Nm 54library can display progress with one of 55.Xr dialog 3 , 56.Xr dialog 1 , 57or 58.Xr Xdialog 1 59.Pq x11/xdialog from the ports tree . 60.Pp 61The 62.Fn dpv 63.Fa config 64argument properties for configuring global display features: 65.Bd -literal -offset indent 66struct dpv_config { 67 uint8_t keep_tite; /* Cleaner exit for scripts */ 68 enum dpv_display display_type; /* Def. DPV_DISPLAY_LIBDIALOG */ 69 enum dpv_output output_type; /* Default DPV_OUTPUT_NONE */ 70 int debug; /* Enable debug on stderr */ 71 int display_limit; /* Files/page. Default -1 */ 72 int label_size; /* Label size. Default 28 */ 73 int pbar_size; /* Mini-progress size */ 74 int dialog_updates_per_second; /* Default 16 */ 75 int status_updates_per_second; /* Default 2 */ 76 uint16_t options; /* Default 0 (none) */ 77 char *title; /* Widget title */ 78 char *backtitle; /* Widget backtitle */ 79 char *aprompt; /* Append. Default NULL */ 80 char *pprompt; /* Prefix. Default NULL */ 81 char *msg_done; /* Default `Done' */ 82 char *msg_fail; /* Default `Fail' */ 83 char *msg_pending; /* Default `Pending' */ 84 char *output; /* Output format string */ 85 const char *status_solo; /* dialog(3) solo-status format. 86 * Default DPV_STATUS_SOLO */ 87 const char *status_many; /* dialog(3) many-status format. 88 * Default DPV_STATUS_MANY */ 89 90 /* 91 * Function pointer; action to perform data transfer 92 */ 93 int (*action)(struct dpv_file_node *file, int out); 94}; 95 96enum dpv_display { 97 DPV_DISPLAY_LIBDIALOG = 0, /* Use dialog(3) (default) */ 98 DPV_DISPLAY_STDOUT, /* Use stdout */ 99 DPV_DISPLAY_DIALOG, /* Use spawned dialog(1) */ 100 DPV_DISPLAY_XDIALOG, /* Use spawned Xdialog(1) */ 101}; 102 103enum dpv_output { 104 DPV_OUTPUT_NONE = 0, /* No output (default) */ 105 DPV_OUTPUT_FILE, /* Read `output' member as file path */ 106 DPV_OUTPUT_SHELL, /* Read `output' member as shell cmd */ 107}; 108.Ed 109.Pp 110The 111.Va options 112member of the 113.Fn dpv 114.Fa config 115argument is a mask of bit fields indicating various processing options. 116Possible flags are: 117.Bl -tag -width DPV_NO_OVERRUN 118.It Dv DPV_TEST_MODE 119Enable test mode. 120In test mode, 121the 122.Fn action 123callback of the 124.Fa config 125argument is not called but instead simulated-data is used to drive progress. 126Appends 127.Dq [TEST MODE] 128to the status line 129.Po 130to override, 131set the 132.Va status_format 133member of the 134.Fn dpv 135.Fa config 136argument; 137for example, 138to 139.Dv DPV_STATUS_DEFAULT 140.Pc . 141.It Dv DPV_WIDE_MODE 142Enable wide mode. 143In wide mode, 144the length of the 145.Va aprompt 146and 147.Va pprompt 148members of the 149.Fn dpv 150.Fa config 151argument will bump the width of the gauge widget. 152Prompts wider than the maximum width will wrap 153.Po 154unless using 155.Xr Xdialog 1 ; 156see BUGS section below 157.Pc . 158.It Dv DPV_NO_LABELS 159Disables the display of labels associated with each transfer 160.Po 161.Va label_size 162member of 163.Fn dpv 164.Fa config 165argument is ignored 166.Pc . 167.It Dv DPV_USE_COLOR 168Force the use of color even if the 169.Va display_type 170does not support color 171.Po 172.Ev USE_COLOR 173environment variable is ignored 174.Pc . 175.It Dv DPV_NO_OVERRUN 176When enabled, 177callbacks for the current 178.Vt dpv_file_node 179are terminated when 180.Fn action 181returns 100 or greater 182.Po 183alleviates the need to change the 184.Va status 185of the current 186.Vt dpv_file_node 187but may also cause file truncation if the stream exceeds expected length 188.Pc . 189.El 190.Pp 191The 192.Fa file_list 193argument to 194.Fn dpv 195is a pointer to a 196.Dq linked-list , 197described in 198.In dpv.h : 199.Bd -literal -offset indent 200struct dpv_file_node { 201 enum dpv_status status; /* status of read operation */ 202 char *msg; /* display instead of "Done/Fail" */ 203 char *name; /* name of file to read */ 204 char *path; /* path to file */ 205 long long length; /* expected size */ 206 long long read; /* number units read (e.g., bytes) */ 207 struct dpv_file_node *next;/* pointer to next (end with NULL) */ 208}; 209.Ed 210.Pp 211For each of the items in the 212.Fa file_list 213.Dq linked-list 214argument, 215the 216.Fn action 217callback member of the 218.Fn dpv 219.Fa config 220argument is called. 221The 222.Fn action 223function performs a 224.Dq nominal 225action on the file and return. 226The return value of 227.Vt int 228represents the current progress percentage 229.Pq 0-100 230for the current file. 231.Pp 232The 233.Fn action 234callback provides two variables for each call. 235.Fa file 236provides a reference to the current 237.Vt dpv_file_node 238being processed. 239.Fa out 240provides a file descriptor where the data goes. 241.Pp 242If the 243.Va output 244member of the 245.Fn dpv 246.Fa config 247argument was set to DPV_OUTPUT_NONE 248.Pq default ; when invoking Fn dpv , 249the 250.Fa out 251file descriptor of 252.Fn action 253will be zero and can be ignored. 254If 255.Fa output 256was set to DPV_OUTPUT_FILE, 257.Fa out 258will be an open file descriptor to a file. 259If 260.Fa output 261was set to DPV_OUTPUT_SHELL, 262.Fa out 263will be an open file descriptor to a pipe for a spawned shell program. 264When 265.Fa out 266is greater than zero, 267write data that has been read back to 268.Fa out . 269.Pp 270To abort 271.Fn dpv , 272either from the 273.Fn action 274callback or asynchronously from a signal handler, 275two globals are provided via 276.In dpv.h : 277.Bd -literal -offset indent 278extern int dpv_interrupt; /* Set to TRUE in interrupt handler */ 279extern int dpv_abort; /* Set to true in callback to abort */ 280.Ed 281.Pp 282These globals are not automatically reset and must be manually maintained. 283Do not forget to reset these globals before subsequent invocations of 284.Fn dpv 285when making multiple calls from the same program. 286.Pp 287In addition, 288the 289.Va status 290member of the 291.Fn action 292.Fa file 293argument can be used to control callbacks for the current file. 294The 295.Va status 296member can be set to any of the below from 297.In dpv.h : 298.Bd -literal -offset indent 299enum dpv_status { 300 DPV_STATUS_RUNNING = 0, /* Running (default) */ 301 DPV_STATUS_DONE, /* Completed */ 302 DPV_STATUS_FAILED, /* Oops, something went wrong */ 303}; 304.Ed 305.Pp 306The default 307.Fa status 308is zero, 309DPV_STATUS_RUNNING, 310which keeps the callbacks coming for the current 311.Fn file . 312Setting 313.Ql file->status 314to anything other than DPV_STATUS_RUNNING will cause 315.Fn dpv 316to loop to the next file, 317effecting the next callback, 318if any. 319.Pp 320The 321.Fn action 322callback is responsible for calculating percentages and 323.Pq recommended 324maintaining a 325.Nm 326global counter so 327.Fn dpv 328can display throughput statistics. 329Percentages are reported through the 330.Vt int 331return value of the 332.Fn action 333callback. 334Throughput statistics are calculated from the below global 335.Vt int 336in 337.In dpv.h : 338.Bd -literal -offset indent 339extern int dpv_overall_read; 340.Ed 341.Pp 342Set this to the number of bytes that have been read for all files. 343Throughput information is displayed in the status line 344.Pq only available when using Xr dialog 3 345at the bottom of the screen. 346See DPV_DISPLAY_LIBDIALOG above. 347.Pp 348Note that 349.Va dpv_overall_read 350does not have to represent bytes. 351For example, 352the 353.Va status_format 354can be changed to display something other than 355.Dq Li bytes 356and increment 357.Va dpv_overall_read 358accordingly 359.Pq for example, counting lines . 360.Pp 361When 362.Fn dpv 363is processing the current file, 364the 365.Va length 366and 367.Va read 368members of the 369.Fn action 370.Fa file 371argument are used for calculating the display of mini progress bars 372.Po 373if enabled; 374see 375.Va pbar_size 376above 377.Pc . 378If the 379.Va length 380member of the current 381.Fa file 382is less than zero 383.Pq indicating an unknown file length , 384a 385.Xr humanize_number 3 386version of the 387.Va read 388member is used instead of a traditional progress bar. 389Otherwise a progress bar is calculated as percentage read to file length. 390.Fn action 391callback must maintain these member values for mini-progress bars. 392.Pp 393The 394.Fn dpv_free 395function performs 396.Xr free 3 397on private global variables initialized by 398.Fn dpv . 399.Sh ENVIRONMENT 400The below environment variables are referenced by 401.Nm : 402.Bl -tag -width ".Ev USE_COLOR" 403.It Ev DIALOG 404Override command string used to launch 405.Xr dialog 1 406.Pq requires Dv DPV_DISPLAY_DIALOG 407or 408.Xr Xdialog 1 409.Pq requires Dv DPV_DISPLAY_XDIALOG ; 410default is either 411.Ql dialog 412.Pq for Dv DPV_DISPLAY_DIALOG 413or 414.Ql Xdialog 415.Pq for Dv DPV_DISPLAY_XDIALOG . 416.It Ev DIALOGRC 417If set and non-NULL, 418path to 419.Ql .dialogrc 420file. 421.It Ev HOME 422If 423.Ql Ev $DIALOGRC 424is either not set or NULL, 425used as a prefix to 426.Ql .dialogrc 427.Pq that is, Ql $HOME/.dialogrc . 428.It Ev USE_COLOR 429If set and NULL, 430disables the use of color when using 431.Xr dialog 1 432.Pq does not apply to Xr Xdialog 1 . 433.It Ev msg_done Ev msg_fail Ev msg_pending 434Internationalization strings for overriding the default English strings 435.Ql Done , 436.Ql Fail , 437and 438.Ql Pending 439respectively. 440To prevent their usage, 441explicitly set the 442.Va msg_done , 443.Va msg_fail , 444and 445.Va msg_pending 446members of 447.Fn dpv 448.Fa config 449argument to default macros 450.Pq DPV_DONE_DEFAULT, DPV_FAIL_DEFAULT, and DPV_PENDING_DEFAULT 451or desired values. 452.El 453.Sh FILES 454.Bl -tag -width ".Pa $HOME/.dialogrc" -compact 455.It Pa $HOME/.dialogrc 456.El 457.Sh SEE ALSO 458.Xr dialog 1 , 459.Xr Xdialog 1 , 460.Xr dialog 3 461.Sh HISTORY 462The 463.Nm 464library first appeared in 465.Fx 10.2 . 466.Sh AUTHORS 467.An Devin Teske Aq dteske@FreeBSD.org 468.Sh BUGS 469.Xr Xdialog 1 , 470when given both 471.Ql Fl -title Ar title 472.Po 473see above 474.Ql Va title 475member of 476.Va struct dpv_config 477.Pc 478and 479.Ql Fl -backtitle Ar backtitle 480.Po 481see above 482.Ql Va backtitle 483member of 484.Va struct dpv_config 485.Pc , 486displays the backtitle in place of the title and vice-versa. 487.Pp 488.Xr Xdialog 1 489does not wrap long prompt texts received after initial launch. 490This is a known issue with the 491.Ql --gauge 492widget in 493.Xr Xdialog 1 . 494Embed escaped newlines within prompt text to force line breaks. 495.Pp 496.Xr dialog 1 497does not display the first character after a series of escaped escape-sequences 498(for example, ``\\\\n'' produces ``\\'' instead of ``\\n''). 499This is a known issue with 500.Xr dialog 1 501and does not affect 502.Xr dialog 3 503or 504.Xr Xdialog 1 . 505.Pp 506If an application ignores 507.Ev USE_COLOR 508when set and NULL before calling 509.Fn dpv 510with color escape sequences anyway, 511.Xr dialog 3 512and 513.Xr dialog 1 514may not render properly. 515Workaround is to detect when 516.Ev USE_COLOR 517is set and NULL and either not use color escape sequences at that time or use 518.Xr unsetenv 3 519to unset 520.Ev USE_COLOR , 521forcing interpretation of color sequences. 522This does not effect 523.Xr Xdialog 1 , 524which renders the color escape sequences as plain text. 525See 526.Do 527embedded "\\Z" sequences 528.Dc 529in 530.Xr dialog 1 531for additional information. 532